|
| 1 | +import os |
| 2 | +import pytest |
| 3 | +import boto3 |
| 4 | +from playwright.sync_api import sync_playwright, expect |
| 5 | +import time |
| 6 | +import random |
| 7 | +import string |
| 8 | + |
| 9 | +@pytest.fixture(scope="session") |
| 10 | +def browser(): |
| 11 | + with sync_playwright() as p: |
| 12 | + browser = p.chromium.launch(headless=True, slow_mo=1000) |
| 13 | + yield browser |
| 14 | + browser.close() |
| 15 | + |
| 16 | +@pytest.fixture(scope="session") |
| 17 | +def page(browser): |
| 18 | + context = browser.new_context() |
| 19 | + page = context.new_page() |
| 20 | + yield page |
| 21 | + context.close() |
| 22 | + |
| 23 | +@pytest.fixture(scope="session") |
| 24 | +def app_url(): |
| 25 | + cloudfront = boto3.client('cloudfront', endpoint_url='http://localhost:4566') |
| 26 | + response = cloudfront.list_distributions() |
| 27 | + distribution_id = response['DistributionList']['Items'][0]['Id'] |
| 28 | + return f"https://{distribution_id}.cloudfront.localhost.localstack.cloud" |
| 29 | + |
| 30 | +def test_quiz_flow(page, app_url): |
| 31 | + # Enable verbose logging |
| 32 | + # page.set_viewport_size({"width": 1280, "height": 720}) |
| 33 | + |
| 34 | + # Navigate to home page |
| 35 | + print("\nNavigating to home page...") |
| 36 | + page.goto(app_url) |
| 37 | + expect(page.get_by_text("Welcome")).to_be_visible() |
| 38 | + |
| 39 | + # Select AWS Quiz from public quizzes |
| 40 | + print("Selecting AWS Quiz...") |
| 41 | + quiz_select = page.get_by_label("Select a Public Quiz") |
| 42 | + quiz_select.click() |
| 43 | + page.get_by_text("AWS Quiz").click() |
| 44 | + |
| 45 | + # Fill in user details |
| 46 | + username = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) |
| 47 | + print(f"Username: {username}") |
| 48 | + email = f"{username}@example.com" |
| 49 | + print(f"Email: {email}") |
| 50 | + print("Filling in user details...") |
| 51 | + username_input = page.get_by_label("Username") |
| 52 | + username_input.fill(username) |
| 53 | + email_input = page.get_by_label("Email (Optional)") |
| 54 | + email_input.fill(email) |
| 55 | + |
| 56 | + # Start the quiz |
| 57 | + print("Starting quiz...") |
| 58 | + start_button = page.get_by_text("Start Playing") |
| 59 | + expect(start_button).to_be_enabled() |
| 60 | + start_button.click() |
| 61 | + |
| 62 | + # Wait for first question to load |
| 63 | + print("Waiting for first question...") |
| 64 | + expect(page.get_by_text("Question 1 / 5")).to_be_visible() |
| 65 | + |
| 66 | + # Answer all questions |
| 67 | + answers = [ |
| 68 | + "B. Amazon EC2", # What is the primary compute service in AWS? |
| 69 | + "A. Simple Storage Service", # What does S3 stand for in AWS? |
| 70 | + "A. Amazon DynamoDB", # Which AWS service is a NoSQL database? |
| 71 | + "B. AWS Lambda", # Which AWS service lets you run code without provisioning servers? |
| 72 | + "B. Identity and Access Management" # What is IAM used for? |
| 73 | + ] |
| 74 | + |
| 75 | + for i, answer in enumerate(answers): |
| 76 | + print(f"Answering question {i + 1}...") |
| 77 | + # Wait for question to be visible |
| 78 | + expect(page.get_by_text(f"Question {i + 1} / 5")).to_be_visible() |
| 79 | + |
| 80 | + # Select answer |
| 81 | + answer_radio = page.get_by_label(answer) |
| 82 | + expect(answer_radio).to_be_visible() |
| 83 | + answer_radio.click() |
| 84 | + |
| 85 | + # Wait for next question or submit button |
| 86 | + time.sleep(2) |
| 87 | + |
| 88 | + # Try to find score text with a more flexible approach |
| 89 | + score_element = page.get_by_text("Score", exact=False) |
| 90 | + if score_element: |
| 91 | + print(f"Found score element: {score_element.text_content()}") |
| 92 | + |
| 93 | + # Click View Leaderboard |
| 94 | + print("Clicking leaderboard button...") |
| 95 | + leaderboard_button = page.get_by_text("View Leaderboard") |
| 96 | + expect(leaderboard_button).to_be_visible() |
| 97 | + leaderboard_button.click() |
| 98 | + time.sleep(10) |
| 99 | + |
| 100 | + # Verify leaderboard loaded |
| 101 | + print("Verifying leaderboard...") |
| 102 | + expect(page.get_by_text("LEADERBOARD")).to_be_visible() |
| 103 | + |
| 104 | + # Check both podium and list views for the username |
| 105 | + print("Checking leaderboard entries...") |
| 106 | + found_user = False |
| 107 | + |
| 108 | + # Check podium entries |
| 109 | + podium_entries = page.locator('.podium h5').all() |
| 110 | + for entry in podium_entries: |
| 111 | + content = entry.text_content() |
| 112 | + print(f"Podium entry: {content}") |
| 113 | + if username in content: |
| 114 | + found_user = True |
| 115 | + break |
| 116 | + |
| 117 | + # If not found in podium, check list entries |
| 118 | + if not found_user: |
| 119 | + list_entries = page.locator('.MuiListItemText-primary').all() |
| 120 | + for entry in list_entries: |
| 121 | + content = entry.text_content() |
| 122 | + print(f"List entry: {content}") |
| 123 | + if username in content: |
| 124 | + found_user = True |
| 125 | + break |
| 126 | + |
| 127 | + assert found_user, "User not found in leaderboard" |
| 128 | + |
| 129 | +def test_quiz_creation(page, app_url): |
| 130 | + print("\nStarting quiz creation test...") |
| 131 | + |
| 132 | + # Navigate to home page |
| 133 | + print("Navigating to home page...") |
| 134 | + page.goto(app_url) |
| 135 | + |
| 136 | + # Click Create a New Quiz |
| 137 | + print("Clicking Create a New Quiz...") |
| 138 | + page.get_by_text("Create a New Quiz").click() |
| 139 | + |
| 140 | + # Fill in quiz details |
| 141 | + print("Filling quiz title...") |
| 142 | + page.get_by_label("Quiz Title").fill("Test Quiz") |
| 143 | + |
| 144 | + # Add a question |
| 145 | + print("Adding question text...") |
| 146 | + question_input = page.get_by_role("textbox", name="Question Text") |
| 147 | + question_input.fill("What is LocalStack?") |
| 148 | + |
| 149 | + # Fill options |
| 150 | + options = [ |
| 151 | + "A. A cloud service emulator", |
| 152 | + "B. A database system", |
| 153 | + "C. A web framework", |
| 154 | + "D. A programming language" |
| 155 | + ] |
| 156 | + |
| 157 | + print("Filling options...") |
| 158 | + for i, option in enumerate(options): |
| 159 | + # Use role selector for textbox with specific name |
| 160 | + option_input = page.get_by_role("textbox", name=f"Option {i + 1}") |
| 161 | + option_input.fill(option) |
| 162 | + |
| 163 | + # Add trivia |
| 164 | + print("Adding trivia...") |
| 165 | + trivia_input = page.get_by_role("textbox", name="Trivia") |
| 166 | + trivia_input.fill("LocalStack is a cloud service emulator that runs in a single container on your laptop.") |
| 167 | + |
| 168 | + # Select correct answer using radio group |
| 169 | + print("Selecting correct answer...") |
| 170 | + radio_group = page.get_by_role("radiogroup") |
| 171 | + expect(radio_group).to_be_visible() |
| 172 | + |
| 173 | + # Select the first option (A) as correct answer |
| 174 | + correct_answer = page.locator('input[type="radio"]').first |
| 175 | + expect(correct_answer).to_be_visible() |
| 176 | + correct_answer.check() |
| 177 | + |
| 178 | + # Add question |
| 179 | + print("Adding question...") |
| 180 | + add_question_button = page.get_by_role("button", name="Add Question") |
| 181 | + expect(add_question_button).to_be_enabled() |
| 182 | + add_question_button.click() |
| 183 | + |
| 184 | + # Submit quiz |
| 185 | + print("Submitting quiz...") |
| 186 | + submit_button = page.get_by_role("button", name="Submit Quiz") |
| 187 | + expect(submit_button).to_be_enabled() |
| 188 | + submit_button.click() |
| 189 | + |
| 190 | + # Verify quiz was created |
| 191 | + print("Verifying quiz creation...") |
| 192 | + success_message = page.get_by_text("Quiz created successfully!") |
| 193 | + expect(success_message).to_be_visible() |
| 194 | + |
| 195 | + # Get Quiz ID from success message |
| 196 | + success_text = success_message.text_content() |
| 197 | + quiz_id = success_text.split("Quiz ID: ")[1] |
| 198 | + print(f"Quiz created with ID: {quiz_id}") |
| 199 | + |
| 200 | + # Go back to home |
| 201 | + print("Going back to home...") |
| 202 | + page.get_by_text("Go to Home").click() |
| 203 | + |
| 204 | + # Verify we can find and start the new quiz |
| 205 | + print("Starting the created quiz...") |
| 206 | + quiz_id_input = page.get_by_label("Quiz ID") |
| 207 | + quiz_id_input.fill(quiz_id) |
| 208 | + |
| 209 | + username = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) |
| 210 | + print(f"Using username: {username}") |
| 211 | + username_input = page.get_by_label("Username") |
| 212 | + username_input.fill(username) |
| 213 | + |
| 214 | + start_button = page.get_by_text("Start Playing") |
| 215 | + expect(start_button).to_be_enabled() |
| 216 | + start_button.click() |
| 217 | + |
| 218 | + # Verify question appears |
| 219 | + print("Verifying question appears...") |
| 220 | + expect(page.get_by_text("What is LocalStack?")).to_be_visible() |
| 221 | + print("Quiz creation test completed successfully!") |
0 commit comments