Gains:
- Ability to produce robust UI test code with artificial intelligence, including data-testid, open wait, and assert that verifies the real user result
- Ability to avoid fragile tests (bad selector, blind wait) and make tests easy to maintain in the Page Object Model structure
- Ability to test every UI test produced by breaking the code and detect and fix fake-passed tests
Every click, every form fill, every page transition a user makes in a browser can't be tested over and over again by hand — that's why UI test automation (user interface; these tests mimic user behavior by programmatically driving a real browser) exists. Selenium, Playwright and Cypress are the most common tools for this job. Artificial intelligence (AI) is highly skilled at writing the code for these tools: you describe a test case, AI gives you a draft of a workable automation script. But here the central warning of this module comes into play again: UI test code that the AI produces can often be fragile tests that “light up green but verify the wrong thing” or flap in the wind. Your job is not to run this code, but to make sure that it actually robustly verifies the right thing.
In this unit, we aim to produce robust, maintainable and truly validating UI tests with AI; You will learn to avoid fragile tests.
The three pillars of solid UI testing
1. Correct element locator. A test uses a selector to find the element on the page. AI often produces brittle selectors: long XPath paths (address overly dependent on page structure), selectors based on CSS class names (break when design changes). The robust way is stable attributes like data-testid that the developer added for testing. Explicitly impose this on the AI.
2. Explicit wait. The number one source of vulnerability in UI testing is timing. The constant sleep(3) (blind wait) is bad practice: sometimes it's not enough, sometimes it wastes time. The correct way is to use explicit wait, which says "wait until this element appears". Playwright does this largely automatically; In Selenium you must explicitly request it.
3. Meaningful assertion. The test should verify the result the user will actually see — like “order number appeared on the screen,” not just “page loaded.” If the test produced by the AI does not have an assertion or is unimportant, that test produces a pseudo-pass (1st unit).
Caution: When you first see an AI-generated UI test, check three things at most: are the selectors committed (data-testid), are waits on (no blind sleep), and does the assert verify the actual user result? If these three are OK, the test is probably solid.
Page Object Model
As tests grow larger, writing selectors inside each test becomes a maintenance nightmare. Page Object Model (POM — design pattern that collects selectors and actions for each page/screen into a single class) keeps the selector in one place; When the interface changes, you update it in a single file. Have the AI produce the tests in a POM structure, rather than directly; This makes maintenance radically easier.
Weak prompt / Strong prompt
Weak: "Write a Selenium test for the login page."
Strong: "Write a login flow test with Playwright (TypeScript). Selectors only use data-testid; do not use control what the user sees, not the page title.”
Powerful prompt; The tool gives the language, selector policy, wait strategy, architecture (POM) and expressive assert expectation.
Test data and environment independence
A solid UI test is not only written correctly, but also builds and cleans its own test data. AI-generated tests often link to a user or record that is assumed to already exist in the environment (“log in as admin user”). This assumption breaks when the test runs in another environment or after another test (order dependency problem in unit 9). The truth is that every test creates the data it needs at the beginning of the test (or prepares it with an API call) and cleans it at the end. Explicitly instruct the AI to "set up any data this test depends on within the test; do not assume ready-made data from outside."
Another critical point is not to do UI testing with real user data. If a production database copy is used in the test environment, these records are data of real persons; screenshots and test recordings may reveal this data. Use synthetic (fictional) test accounts; it both protects confidentiality and makes tests reproducible. Conducting a "order cancellation" test with a real customer account is both an ethical and operational mistake.
Tip: Keep UI tests as few as possible; Leave the actual verification to the API and unit tests, which are fast and stable. UI testing is expensive and brittle — only use it to validate truly end-to-end user flow (test pyramid logic).
Vehicle comparison
feature
selenium
playwright
cypress
languages
Java, C#, Python, JS
JS/TS, Python, .NET, Java
JavaScript/TypeScript
auto standby
No (by hand)
Yes (strong)
Yes
Multi browser
wide
Chromium/Firefox/WebKit
Chromium-dominant
tendency to brittleness
High (manual standby)
low
low
Ease of learning
medium
easy
easy
parallel operation
Grid required
built-in
Resident/paid
When requesting a code from AI, state clearly which vehicle it belongs to; Otherwise, it may produce confusing, non-working code.
Four copyable templates
1) Solid UI test generation:
Your role: senior test automation engineer.Write tests with [tool + language] for the following flow: [flow].Rules:- Selectors data-testid only; Using XPath/CSS-class. - No blind sleep; Use explicit/automatic wait. - Apply Page Object Model. - Let each assert verify the actual user result. Comment at the beginning of each test which acceptance criteria you are validating.
2) Fragility control:
Examine the following UI test for brittleness:- Is there an unstable selector (long
3) Conversion to Page Object:
Convert the following plain test code into Page Object Model structure. Move selectors and actions to page classes; Let the test file read only the scenario flow. [Tool/language].Code: [paste code]
4) Pseudo-transition proof:
Prove that this UI test actually validates: What single change do I make to the application code that will turn this test RED? If you cannot find a change that will break the test, the test is inadequate; add missing asserts.Test: [paste test]
three mini cases
Case 1 — Liberation from fragile selector. Of the 40 tests one team produced with AI, 70% were broken after an interface update; none of them were actual bugs, they were all fragile XPath selectors. The team converted the tests into a data-testid base with the "fragility check" template. Over the next three interface updates, the number of false breaks dropped to zero; maintenance time decreased from 6 hours to 30 minutes per week.
Case 2 — Fake-passing UI test. AI produced an “add to cart” test; the test was green. When the "fake-proof-of-passage" template was run, the test appeared to only check the button click and page title, never verifying whether the cart counter had increased or not. Even if the cart logic was completely broken, the test passed. Added true assert (cart badge being "1").
Case 3 — Blind waiting trap. In the Selenium test produced by AI, there was sleep(2) after each step; 60 tests took 14 minutes and still broke occasionally. After switching to open wait (wait for the element to be clickable) the time went down to 5 minutes and the brittleness disappeared. Blind waiting was both slow and unreliable.
Common mistakes
- Agreeing to fragile selectors. Using the long XPaths generated by the AI as is; Tests crash at the first interface change.
- Leaving blind `sleep`. "Resolving" the timing with a fixed wait; both slow and indecisive.
- Trivial assert. Just verify that the page has loaded; not checking the actual user result (fake-pass).
- Grow without POM. Distribute selectors to each test; Manually updating dozens of files when the interface changes.
- Not specifying the tool. Not telling the AI what tool/language you want; getting messy, non-working code.
- Trusting when you run the generated code and pass. Not testing by breaking the code.
In summary
UI testing automation verifies user behavior by driving the actual browser with the program. AI generates this code quickly, but there are two big pitfalls: brittle tests (bad selector, blind await) and fake-passing tests (incomplete/trivial assert). The three pillars of solid UI testing are the commit selector (data-testid), explicit await, and assert that verifies the actual user result. Having tests generated in the Page Object Model radically simplifies maintenance. Test each generated test with the question "what change will break this?"
Application task
Select a user flow from your own project (e.g. login or search). Have the AI write tests with the “robust UI test generation” template. Then: (1) check and fix the selectors and waits with a "fragility check", (2) prove that each test actually validates with a "pseudo-pass proof", (3) break the code and observe that the test turns red. Report the number of tests produced and corrected, and the number of vulnerabilities and pseudo-passes you found.
checklist
- [ ] I gave the AI the tool, language, selector policy and architecture (POM) clearly.
- [ ] I verified that the selectors are data-testid.
- [ ] I made sure to use explicit/automatic wait instead of blind sleep.
- [ ] I checked that each assert verifies the actual user result.
- [ ] I tested each test by breaking the code; I saw it turn red.
- [ ] I collected the tests in the Page Object Model structure.