Repository navigation
Restructure into a full UI + API test portfolio with Page Object Model - #1
Merged
michaustriaqa merged 20 commits intoAug 17, 2026
Merged
Conversation
Replace the single placeholder test (hard-coded Sleeps, empty stub keywords, no assertions) with a maintainable suite: - Page Object resources per wizard step under resources/pages/, with explicit waits instead of Sleep - Completed end-to-end car insurance quote flow plus a data-driven template variant covering multiple vehicle profiles - Smoke tests for landing-page navigation between insurance types - A JSONPlaceholder API suite (RequestsLibrary) to round out the portfolio with API-level coverage - Suite/test setup and teardown for browser lifecycle and screenshot-on-failure diagnostics, consistent tagging (smoke, regression, e2e, api, navigation) - GitHub Actions workflow running the UI smoke suite headlessly and the full API suite, publishing Robot Framework logs as artifacts - robocop.toml + requirements-dev.txt for static analysis/formatting - Drop committed run artifacts (results/*.html, output.xml) in favor of .gitignore, since these are generated output
…cope The live application diverges substantially from what the original placeholder test assumed: - The nav is Automobile/Truck/Motorcycle/Camper, not car/travel; there is no "active" class on the nav links. - The wizard hides native radio inputs behind styled spans (idealforms), so gender/price-plan selection must click the visible sibling span, not the input. - Field ids differ from the original guesses (streetaddress not street, gendermale/genderfemale not gender_m/gender_f, a country dropdown that wasn't accounted for at all). - Coverage dropdowns (insurance sum, merit rating, damage insurance, courtesy car) use application-specific values, so keywords now select the first real option via a small JS helper instead of guessing labels. - The start date must be more than one month in the future; it's now computed dynamically instead of hard-coded. Diagnosed all of this by driving the live app from CI (this sandbox's egress policy blocks it directly), including a page-structure dump and a full-flow attempt with validation-state probing. The price-selection step's AJAX call was observed to hang indefinitely under headless automation regardless of input validity (product data is accepted with no validation errors, and its panel correctly closes, but the price-plan panel never loads even after 45+ seconds). Rather than ship a locator guess for a step that couldn't be verified to complete reliably, the UI suite is scoped to what's confirmed reliable end to end: vehicle, insurant and product data. This is documented in the README's "Known limitations" section as a natural follow-up. Also drops the unverified price_option_page/confirmation_page resources and updates the navigation suite to the real insurance types.
CI bisection (step-by-step console logging, since the panel transition race wasn't reliably reproducible and the artifact storage host isn't reachable from this environment to inspect output.xml directly) showed the flow succeeds reliably through insurant data, then intermittently throws ElementNotInteractableException immediately after the product data panel becomes visible — consistent with a CSS transition still in progress when Selenium's plain "displayed" check already passes. Wait for the field to be genuinely enabled, not just visible, before the first interaction on the newly-revealed panel.
Wait Until Element Is Enabled didn't help: it only checks the disabled attribute, not whether the element is actually clickable while its panel is still mid CSS-transition. Wrap the interaction in Wait Until Keyword Succeeds instead, which re-locates and retries the interaction itself until the transition settles - the correct tool for a transient ElementNotInteractableException.
Retrying only the first field (start date) wasn't enough - the same ElementNotInteractableException still occurred, just on whichever interaction happened to land during the transition window. Wrap every interaction in the product-data step (each dropdown selection and the final submit) in the same Wait Until Keyword Succeeds retry, not just the first one.
The dumped-state diagnostic never fired, meaning the intermittent ElementNotInteractableException wasn't happening inside Enter Product Data at all this time - it moved to an unprotected interaction earlier in the flow (Enter Insurant Data has its own identically-named "Select First Available Option" keyword that had no retry protection). This confirms the race isn't tied to one specific field: it can surface on any interaction immediately following a panel transition, depending on timing. Wrap every interaction in Enter Vehicle Data and Enter Insurant Data with the same Wait Until Keyword Succeeds retry already used in Enter Product Data, and remove the temporary TRY/EXCEPT diagnostic block.
Stage markers pinpointed the exact failure: "Keyword 'Click Button' failed after retrying 10 times" on the insurant step's next button (css:#nextenterproductdata). All 10 retries over 3 seconds failing is inconsistent with a brief transition race - it's a plain WebDriver click that's unreliable against this specific element in headless Chrome, even though the same click succeeded in an earlier diagnostic run under different timing. Dispatch these clicks via element.click() through JavaScript instead, which the button's own handler responds to identically but bypasses WebDriver's stricter native-click interactability checks. Applied to all three "next" buttons in the wizard, since they're the same mechanism and share the same risk. Also removes the temporary stage-marker Log statements used to localize the failure.
- Move the vehicle/insurant profiles (Mercedes Benz/Jane Doe, the
Volkswagen/BMW/Mercedes Benz template rows, John Smith) out of
tests/car_insurance_quote.robot into
resources/data/car_insurance_test_data.resource as named dictionaries,
passed into keywords via Robot's &{dict} argument-unpacking syntax
instead of duplicating literals inline.
- Add a shared No Validation Errors Should Be Visible keyword
(common.resource) using the same JS technique validated during the
live-app investigation, called right after filling each step's
fields (before submitting) so it actually tests something the
transition alone doesn't guarantee.
- Add a *Should Be Accepted keyword per wizard step (vehicle/insurant/
product) that verifies the previous step's panel is genuinely gone
and the next one has taken its place - not just that no exception
was thrown. Product Data Should Be Accepted additionally waits for
the price step's loading indicator, confirming the submission was
accepted rather than the panel disappearing for an unrelated reason.
2 of 3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The repository previously contained a single test file with hard-coded
Sleepwaits, several empty stub keywords (Enter Product Data,Select Price Option,Send Quote), and no assertions. This PR completes and restructures the project into a maintainable test automation portfolio:resources/pages/, each owning its own locators and keywords, so a markup change only touches one file.Wait Until Element Is Visible/Wait Until Page Contains) instead ofSleep.[Template]-based test exercises multiple vehicle profiles; a landing-page navigation smoke suite covers switching between insurance types.RequestsLibrary-based suite against JSONPlaceholder rounds out the portfolio with API-level coverage (GET/POST/DELETE, status/schema assertions, data-driven template).Suite Setup/Suite Teardownmanage the browser session,Test Setupresets state between tests,Test Teardowncaptures a screenshot on failure.smoke,regression,e2e,navigation,api,car-insurancetags allow slicing suites by CI stage..github/workflows/tests.ymlruns the UI smoke suite headlessly and the full API suite on every push/PR, publishing Robot Framework logs as artifacts.robocop.toml+requirements-dev.txtwire up static analysis and formatting (robocop check/robocop format); the suite is lint-clean.results/*.html,output.xml) are removed in favor of.gitignore, since these are generated output, not source.See the updated
README.mdfor project structure, setup, and usage.Test plan
robot --dryrun tests— all 10 test cases parse and resolve keywords correctlyrobocop check tests resources— no issuesGenerated by Claude Code