@vardot/varbase-e2e 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +148 -0
- package/CLAUDE.md +544 -0
- package/README.md +22 -0
- package/bin/generate-reports.js +363 -0
- package/bin/init-varbase-e2e.js +330 -0
- package/bin/postinstall.js +26 -0
- package/cucumber.js +125 -0
- package/docs/00-quick-start.md +102 -0
- package/docs/01-getting-started.md +102 -0
- package/docs/02-bbr-smart-waits.md +77 -0
- package/docs/03-selector-registry.md +95 -0
- package/docs/04-step-reference.md +801 -0
- package/docs/05-web-first-assertions.md +91 -0
- package/docs/06-network-and-dialogs.md +83 -0
- package/docs/07-auth-state.md +75 -0
- package/docs/08-clock-mocking.md +59 -0
- package/docs/09-api-testing.md +114 -0
- package/docs/10-accessibility.md +167 -0
- package/docs/11-debugging.md +129 -0
- package/docs/12-ai-agent-guide.md +338 -0
- package/docs/13-faq.md +236 -0
- package/docs/14-recipes-cookbook.md +255 -0
- package/docs/15-tag-conventions.md +76 -0
- package/docs/16-ci-cd.md +90 -0
- package/docs/README.md +125 -0
- package/docs/advanced-screenshots/then-i-save-fullscreen-screenshot.md +36 -0
- package/docs/advanced-screenshots/then-i-save-width-x-height-screenshot.md +34 -0
- package/docs/advanced-screenshots/when-i-save-screenshot-name-filename.md +45 -0
- package/docs/advanced-screenshots.md +52 -0
- package/docs/advanced-selectors.md +18 -0
- package/docs/api-step-definitions.md +45 -0
- package/docs/global-settings.md +267 -0
- package/docs/install-varbase-e2e/ddev-varbase-e2e.md +52 -0
- package/docs/install-varbase-e2e.md +34 -0
- package/docs/overview.md +40 -0
- package/docs/step-definitions/given-i-am-anonymous-user.md +67 -0
- package/docs/step-definitions/given-i-am-homepage.md +68 -0
- package/docs/step-definitions/given-i-am-specific-page.md +72 -0
- package/docs/step-definitions/then-i-should-be.md +56 -0
- package/docs/step-definitions/then-i-should-see.md +62 -0
- package/docs/step-definitions/then-item-checkbox.md +54 -0
- package/docs/step-definitions/then-item-link-should-contain-url.md +84 -0
- package/docs/step-definitions/then-item-should-contain.md +67 -0
- package/docs/step-definitions/then-radio-button-value-should-be-selected.md +68 -0
- package/docs/step-definitions/then-response-status-code-should-be-number.md +69 -0
- package/docs/step-definitions/then-value-radio-button-selected.md +62 -0
- package/docs/step-definitions/when-i-attach-file-file-name-element.md +71 -0
- package/docs/step-definitions/when-i-check-checkbox.md +60 -0
- package/docs/step-definitions/when-i-click-link.md +51 -0
- package/docs/step-definitions/when-i-click-operation-text-row.md +71 -0
- package/docs/step-definitions/when-i-fill.md +59 -0
- package/docs/step-definitions/when-i-go-homepage.md +60 -0
- package/docs/step-definitions/when-i-go-specific-page.md +67 -0
- package/docs/step-definitions/when-i-move-backward-one-page.md +49 -0
- package/docs/step-definitions/when-i-move-forward-one-page.md +58 -0
- package/docs/step-definitions/when-i-press-button.md +58 -0
- package/docs/step-definitions/when-i-reload-page.md +51 -0
- package/docs/step-definitions/when-i-scroll.md +73 -0
- package/docs/step-definitions/when-i-select-option-select-list.md +53 -0
- package/docs/step-definitions/when-i-select-radio-button-value.md +62 -0
- package/docs/step-definitions/when-i-uncheck-checkbox.md +57 -0
- package/docs/step-definitions/when-i-wait-ajax-finish.md +64 -0
- package/docs/step-definitions/when-i-wait.md +62 -0
- package/docs/step-definitions.md +82 -0
- package/docs/steps/README.md +137 -0
- package/docs/steps/a11y.md +731 -0
- package/docs/steps/action.md +181 -0
- package/docs/steps/api.md +679 -0
- package/docs/steps/assertion.md +328 -0
- package/docs/steps/auth.md +108 -0
- package/docs/steps/clock.md +171 -0
- package/docs/steps/cookie.md +293 -0
- package/docs/steps/debug.md +52 -0
- package/docs/steps/dialog.md +226 -0
- package/docs/steps/drupal-canvas.md +414 -0
- package/docs/steps/drupal-ckeditor.md +118 -0
- package/docs/steps/drupal-core.md +688 -0
- package/docs/steps/drupal-layout-builder.md +437 -0
- package/docs/steps/drupal-media.md +107 -0
- package/docs/steps/drupal-moderation.md +81 -0
- package/docs/steps/drupal-paragraphs.md +36 -0
- package/docs/steps/element.md +455 -0
- package/docs/steps/field.md +648 -0
- package/docs/steps/file-download.md +235 -0
- package/docs/steps/form.md +344 -0
- package/docs/steps/iframe.md +248 -0
- package/docs/steps/input.md +220 -0
- package/docs/steps/javascript.md +111 -0
- package/docs/steps/keyboard.md +107 -0
- package/docs/steps/link.md +217 -0
- package/docs/steps/metatag.md +99 -0
- package/docs/steps/modal.md +232 -0
- package/docs/steps/navigation.md +275 -0
- package/docs/steps/network.md +284 -0
- package/docs/steps/path.md +203 -0
- package/docs/steps/response.md +102 -0
- package/docs/steps/responsive.md +139 -0
- package/docs/steps/rest.md +140 -0
- package/docs/steps/screenshot.md +211 -0
- package/docs/steps/scroll.md +266 -0
- package/docs/steps/selectors.md +848 -0
- package/docs/steps/storage.md +254 -0
- package/docs/steps/table.md +216 -0
- package/docs/steps/varbase.md +391 -0
- package/docs/steps/video.md +111 -0
- package/docs/steps/wait.md +553 -0
- package/docs/steps/web-first.md +289 -0
- package/docs/steps/xml.md +505 -0
- package/docs/steps/yaml.md +951 -0
- package/examples/a11y.html +31 -0
- package/examples/about-us.html +11 -0
- package/examples/account.html +32 -0
- package/examples/ajax-wait-examples.html +147 -0
- package/examples/contact-us.html +10 -0
- package/examples/cookies.html +10 -0
- package/examples/date.html +12 -0
- package/examples/dynamic-examples.html +498 -0
- package/examples/element.html +11 -0
- package/examples/example-api.json +28 -0
- package/examples/existing-page.html +11 -0
- package/examples/field.html +24 -0
- package/examples/index.html +37 -0
- package/examples/keyboard.html +11 -0
- package/examples/links.html +9 -0
- package/examples/modal.html +14 -0
- package/examples/path.html +3 -0
- package/examples/table.html +13 -0
- package/examples/test--modal-dialogs.html +252 -0
- package/examples/test--then--i-should--not--see-text-in-element.html +48 -0
- package/examples/test--then--i-should--see-text-in-element.html +48 -0
- package/examples/test--then--i-should--see-text-matching-pattern.html +31 -0
- package/examples/test--then--i-should-see-text-in-table-row.html +232 -0
- package/examples/test--then--the-checkbox-checked.html +68 -0
- package/examples/test--then--the-element-should_not-contain-cssproperty.html +47 -0
- package/examples/test--then--the-link-should-contain.html +21 -0
- package/examples/test--when--i-additionally-select.html +27 -0
- package/examples/test--when--i-attach-file-to-feild.html +50 -0
- package/examples/test--when--i-check-uncheck-checkbox.html +47 -0
- package/examples/test--when--i-click-link.html +18 -0
- package/examples/test--when--i-click-text-in-table-row.html +178 -0
- package/examples/test--when--i-fill-in.html +48 -0
- package/examples/test--when--i-press-button.html +31 -0
- package/examples/test--when--i-reload-page.html +27 -0
- package/examples/test--when--i-scroll-functionality.html +177 -0
- package/examples/test--when--i-scroll-left-right-functionality.html +149 -0
- package/examples/test--when--i-select-option-from-dropdownlist.html +35 -0
- package/examples/test--when--i-select-radio-button.html +95 -0
- package/examples/test--when-i-wait-max-of-time.html +39 -0
- package/examples/test--when-i-wait-page-until-is-loaded.html +47 -0
- package/examples/test--when-i-wait-specific-time.html +39 -0
- package/examples/test-acceptable-url-path.html +11 -0
- package/examples/video-demo.html +43 -0
- package/package.json +56 -0
- package/playwright.config.ts +39 -0
- package/tests/assets/test-document.pdf +14 -0
- package/tests/assets/vardot.png +0 -0
- package/tests/features/a11y.feature +39 -0
- package/tests/features/ajax-wait-examples.feature +24 -0
- package/tests/features/api-step-definitions-individual.feature +185 -0
- package/tests/features/complete-api-testing-examples.feature +205 -0
- package/tests/features/cookie.feature +13 -0
- package/tests/features/date.feature +11 -0
- package/tests/features/dynamic-content-examples.feature +156 -0
- package/tests/features/element.feature +16 -0
- package/tests/features/field.feature +25 -0
- package/tests/features/keyboard.feature +10 -0
- package/tests/features/link.feature +11 -0
- package/tests/features/modal-advanced-example.feature +54 -0
- package/tests/features/modal-basic-example.feature +42 -0
- package/tests/features/modal-error-handling-example.feature +37 -0
- package/tests/features/modal.feature +11 -0
- package/tests/features/path.feature +16 -0
- package/tests/features/response.feature +8 -0
- package/tests/features/responsive.feature +10 -0
- package/tests/features/table.feature +18 -0
- package/tests/features/test--given--i-am-an-anonymous-user.feature +10 -0
- package/tests/features/test--given--i-am-on-homepage.feature +16 -0
- package/tests/features/test--then--i-save-screenshot.feature +33 -0
- package/tests/features/test--then--i-see-locator.feature +320 -0
- package/tests/features/test--then--i-should--not--see-text-in-element.feature +13 -0
- package/tests/features/test--then--i-should--see-text-in-element-by-attr.feature +10 -0
- package/tests/features/test--then--i-should--see-text-in-element.feature +10 -0
- package/tests/features/test--then--i-should--see-text-matching-pattern-in-element.feature +13 -0
- package/tests/features/test--then--i-should--see-text-matching-pattern.feature +18 -0
- package/tests/features/test--then--i-should-be-on-page.feature +10 -0
- package/tests/features/test--then--i-should-be-on-the-homepage.feature +10 -0
- package/tests/features/test--then--i-should-not-see-an-element-by-attr.feature +8 -0
- package/tests/features/test--then--i-should-not-see-an-element.feature +8 -0
- package/tests/features/test--then--i-should-see-an-element-by-attr.feature +8 -0
- package/tests/features/test--then--i-should-see-an-element.feature +8 -0
- package/tests/features/test--then--i-should-see-n-elements.feature +24 -0
- package/tests/features/test--then--i-should-see-text-in-table-row.feature +96 -0
- package/tests/features/test--then--print-current-url-and-response.feature +21 -0
- package/tests/features/test--then--the-checkbox-is-checked.feature +18 -0
- package/tests/features/test--then--the-checkbox-should-be-checked.feature +16 -0
- package/tests/features/test--then--the-element-should-contain-cssproperty.feature +9 -0
- package/tests/features/test--then--the-element-should-not-contain-cssproperty.feature +10 -0
- package/tests/features/test--then--the-field-should-contain-value.feature +11 -0
- package/tests/features/test--then--the-response-should-contain.feature +11 -0
- package/tests/features/test--then--the-response-status-code-should-be.feature +31 -0
- package/tests/features/test--then--the-url-should-match.feature +7 -0
- package/tests/features/test--then-the-link-should-contain-by-attribute.feature +18 -0
- package/tests/features/test--then-the-link-should-contain.feature +7 -0
- package/tests/features/test--when--i-additionally-select.feature +30 -0
- package/tests/features/test--when--i-attach-file-to-feild.feature +9 -0
- package/tests/features/test--when--i-check-checkbox.feature +21 -0
- package/tests/features/test--when--i-click-link-by-attribute.feature +21 -0
- package/tests/features/test--when--i-click-link.feature +9 -0
- package/tests/features/test--when--i-click-text-in-table-row.feature +37 -0
- package/tests/features/test--when--i-fill-in-by-attr.feature +31 -0
- package/tests/features/test--when--i-fill-in-table-by-attr.feature +19 -0
- package/tests/features/test--when--i-fill-in.feature +32 -0
- package/tests/features/test--when--i-follow.feature +22 -0
- package/tests/features/test--when--i-go-to-homepage.feature +9 -0
- package/tests/features/test--when--i-move-forward-backward-one-page.feature +14 -0
- package/tests/features/test--when--i-press-button-by-attribute.feature +18 -0
- package/tests/features/test--when--i-press-button.feature +13 -0
- package/tests/features/test--when--i-reload-page.feature +11 -0
- package/tests/features/test--when--i-scroll-left-right.feature +48 -0
- package/tests/features/test--when--i-scroll.feature +48 -0
- package/tests/features/test--when--i-select-option-from-dropdownlist.feature +21 -0
- package/tests/features/test--when--i-select-radio-button.feature +37 -0
- package/tests/features/test--when--i-wait-page-is-loaded.feature +8 -0
- package/tests/features/test--when--i-wait-time.feature +21 -0
- package/tests/features/video.feature +18 -0
- package/tests/features/wait.feature +7 -0
- package/tests/features/yaml.feature +102 -0
- package/tests/selectors/_canonical-keys.json +113 -0
- package/tests/selectors/back-end-selectors.json +19 -0
- package/tests/selectors/cms-contentful-admin.json +35 -0
- package/tests/selectors/cms-craft-admin.json +39 -0
- package/tests/selectors/cms-drupal-cms-gin.json +56 -0
- package/tests/selectors/cms-drupal-core-claro.json +50 -0
- package/tests/selectors/cms-generic-admin.json +34 -0
- package/tests/selectors/cms-ghost-admin.json +34 -0
- package/tests/selectors/cms-joomla-admin.json +41 -0
- package/tests/selectors/cms-magento2-admin.json +32 -0
- package/tests/selectors/cms-prestashop-admin.json +38 -0
- package/tests/selectors/cms-shopify-admin.json +25 -0
- package/tests/selectors/cms-strapi-admin.json +42 -0
- package/tests/selectors/cms-typo3-admin.json +41 -0
- package/tests/selectors/cms-woocommerce-front.json +50 -0
- package/tests/selectors/cms-wordpress-admin.json +31 -0
- package/tests/selectors/framework-ant-design.json +80 -0
- package/tests/selectors/framework-bootstrap.json +86 -0
- package/tests/selectors/framework-bulma.json +74 -0
- package/tests/selectors/framework-chakra.json +58 -0
- package/tests/selectors/framework-foundation.json +51 -0
- package/tests/selectors/framework-material-ui.json +72 -0
- package/tests/selectors/framework-shadcn.json +51 -0
- package/tests/selectors/framework-tailwind.json +40 -0
- package/tests/selectors/framework-vuetify.json +61 -0
- package/tests/selectors/front-end-selectors.json +16 -0
- package/tests/selectors/homepage-selectors.json +13 -0
- package/tests/step-definitions/a11y.steps.js +800 -0
- package/tests/step-definitions/action.steps.js +167 -0
- package/tests/step-definitions/api.steps.js +732 -0
- package/tests/step-definitions/assertion.steps.js +352 -0
- package/tests/step-definitions/auth.steps.js +126 -0
- package/tests/step-definitions/clock.steps.js +128 -0
- package/tests/step-definitions/cookie.steps.js +216 -0
- package/tests/step-definitions/debug.steps.js +39 -0
- package/tests/step-definitions/dialog.steps.js +193 -0
- package/tests/step-definitions/drupal-canvas.steps.js +764 -0
- package/tests/step-definitions/drupal-ckeditor.steps.js +108 -0
- package/tests/step-definitions/drupal-core.steps.js +665 -0
- package/tests/step-definitions/drupal-helpers.js +371 -0
- package/tests/step-definitions/drupal-layout-builder.steps.js +466 -0
- package/tests/step-definitions/drupal-media.steps.js +99 -0
- package/tests/step-definitions/drupal-moderation.steps.js +71 -0
- package/tests/step-definitions/drupal-paragraphs.steps.js +50 -0
- package/tests/step-definitions/element.steps.js +356 -0
- package/tests/step-definitions/field.steps.js +653 -0
- package/tests/step-definitions/file-download.steps.js +211 -0
- package/tests/step-definitions/form.steps.js +333 -0
- package/tests/step-definitions/iframe.steps.js +228 -0
- package/tests/step-definitions/input.steps.js +202 -0
- package/tests/step-definitions/javascript.steps.js +232 -0
- package/tests/step-definitions/keyboard.steps.js +112 -0
- package/tests/step-definitions/link.steps.js +142 -0
- package/tests/step-definitions/metatag.steps.js +91 -0
- package/tests/step-definitions/modal.steps.js +244 -0
- package/tests/step-definitions/navigation.steps.js +218 -0
- package/tests/step-definitions/network.steps.js +280 -0
- package/tests/step-definitions/path.steps.js +141 -0
- package/tests/step-definitions/response.steps.js +98 -0
- package/tests/step-definitions/responsive.steps.js +125 -0
- package/tests/step-definitions/rest.steps.js +111 -0
- package/tests/step-definitions/screenshot.steps.js +423 -0
- package/tests/step-definitions/scroll.steps.js +189 -0
- package/tests/step-definitions/selectors.steps.js +1003 -0
- package/tests/step-definitions/storage.steps.js +194 -0
- package/tests/step-definitions/table.steps.js +181 -0
- package/tests/step-definitions/varbase-e2e.js +897 -0
- package/tests/step-definitions/varbase.steps.js +458 -0
- package/tests/step-definitions/video.steps.js +178 -0
- package/tests/step-definitions/wait.steps.js +400 -0
- package/tests/step-definitions/web-first.steps.js +298 -0
- package/tests/step-definitions/xml.steps.js +411 -0
- package/tests/step-definitions/yaml.steps.js +913 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# Element interactions steps
|
|
2
|
+
|
|
3
|
+
19 steps, defined in `tests/step-definitions/element.steps.js`.
|
|
4
|
+
|
|
5
|
+
Cucumber-js loads every `*.steps.js` in that directory automatically — you never `require()` a step file from a feature.
|
|
6
|
+
|
|
7
|
+
| # | Step |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| 1 | `Then the element "#footer" should appear after the element "#main"` |
|
|
10
|
+
| 2 | `Then the text "Sign in" should appear after the text "Welcome"` |
|
|
11
|
+
| 3 | `Then the element "a" with the attribute "href" and the value "/about" should exist` |
|
|
12
|
+
| 4 | `Then the element "a" with the attribute "href" and the value containing "/about" should exist` |
|
|
13
|
+
| 5 | `Then the element "a" with the attribute "href" and the value "/admin" should not exist` |
|
|
14
|
+
| 6 | `Then the element "a" with the attribute "href" and the value containing "/old" should not exist` |
|
|
15
|
+
| 7 | `Then the element "#header" should be at the top of the viewport` |
|
|
16
|
+
| 8 | `Then the element ".hero" should be centered in the viewport` |
|
|
17
|
+
| 9 | `When I click on the element "#sign-in"` |
|
|
18
|
+
| 10 | `When I trigger the JS event "click" on the element "#cta"` |
|
|
19
|
+
| 11 | `When I scroll to the element "#footer"` |
|
|
20
|
+
| 12 | `When I hover over the element ".tooltip-trigger"` |
|
|
21
|
+
| 13 | `When I focus on the element "#email"` |
|
|
22
|
+
| 14 | `Then the element "#dashboard" should be displayed` |
|
|
23
|
+
| 15 | `Then the element "#loading-spinner" should not be displayed` |
|
|
24
|
+
| 16 | `Then the element "#hero" should be displayed within a viewport` |
|
|
25
|
+
| 17 | `Then the element "#hero" should be displayed within a viewport with a top offset of 60 pixels` |
|
|
26
|
+
| 18 | `Then the element "#footer" should not be displayed within a viewport with a top offset of 60 pixels` |
|
|
27
|
+
| 19 | `Then the element "#footer" should not be displayed within a viewport` |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 1. Then the element "#footer" should appear after the element "#main"
|
|
32
|
+
|
|
33
|
+
Assert element A is positioned vertically below element B (greater Y).
|
|
34
|
+
|
|
35
|
+
**Keyword**: `Then`
|
|
36
|
+
|
|
37
|
+
**Pattern**
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
'the element {string} should appear after the element {string}'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Examples**
|
|
44
|
+
|
|
45
|
+
```gherkin
|
|
46
|
+
Then the element "#footer" should appear after the element "#main"
|
|
47
|
+
Then the element ".checkout" should appear after the element ".cart"
|
|
48
|
+
And the element "#summary" should appear after the element "#details"
|
|
49
|
+
Then the element "h2" should appear after the element "h1"
|
|
50
|
+
Then the element "[data-testid=cta]" should appear after the element ".hero"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 2. Then the text "Sign in" should appear after the text "Welcome"
|
|
54
|
+
|
|
55
|
+
Assert text A appears after text B in the document body's text order.
|
|
56
|
+
|
|
57
|
+
**Keyword**: `Then`
|
|
58
|
+
|
|
59
|
+
**Pattern**
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
'the text {string} should appear after the text {string}'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Examples**
|
|
66
|
+
|
|
67
|
+
```gherkin
|
|
68
|
+
Then the text "Sign in" should appear after the text "Welcome"
|
|
69
|
+
Then the text "Total" should appear after the text "Subtotal"
|
|
70
|
+
And the text "Footer" should appear after the text "Header"
|
|
71
|
+
Then the text "Privacy" should appear after the text "Terms"
|
|
72
|
+
Then the text "Step 3" should appear after the text "Step 2"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 3. Then the element "a" with the attribute "href" and the value "/about" should exist
|
|
76
|
+
|
|
77
|
+
Assert at least one element matching `<selector>[<attr>="<value>"]` exists.
|
|
78
|
+
|
|
79
|
+
**Keyword**: `Then`
|
|
80
|
+
|
|
81
|
+
**Pattern**
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
'the element {string} with the attribute {string} and the value {string} should exist'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Examples**
|
|
88
|
+
|
|
89
|
+
```gherkin
|
|
90
|
+
Then the element "a" with the attribute "href" and the value "/about" should exist
|
|
91
|
+
Then the element "input" with the attribute "name" and the value "email" should exist
|
|
92
|
+
And the element "button" with the attribute "type" and the value "submit" should exist
|
|
93
|
+
Then the element "div" with the attribute "data-testid" and the value "user-list" should exist
|
|
94
|
+
Then the element "img" with the attribute "alt" and the value "Logo" should exist
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 4. Then the element "a" with the attribute "href" and the value containing "/about" should exist
|
|
98
|
+
|
|
99
|
+
Assert at least one element with attribute value containing a substring exists.
|
|
100
|
+
|
|
101
|
+
**Keyword**: `Then`
|
|
102
|
+
|
|
103
|
+
**Pattern**
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
'the element {string} with the attribute {string} and the value containing {string} should exist'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Examples**
|
|
110
|
+
|
|
111
|
+
```gherkin
|
|
112
|
+
Then the element "a" with the attribute "href" and the value containing "/about" should exist
|
|
113
|
+
Then the element "input" with the attribute "class" and the value containing "is-valid" should exist
|
|
114
|
+
And the element "button" with the attribute "data-testid" and the value containing "cta" should exist
|
|
115
|
+
Then the element "img" with the attribute "src" and the value containing ".png" should exist
|
|
116
|
+
Then the element "div" with the attribute "aria-label" and the value containing "card" should exist
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 5. Then the element "a" with the attribute "href" and the value "/admin" should not exist
|
|
120
|
+
|
|
121
|
+
Assert NO element matches `<selector>[<attr>="<value>"]`.
|
|
122
|
+
|
|
123
|
+
**Keyword**: `Then`
|
|
124
|
+
|
|
125
|
+
**Pattern**
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
'the element {string} with the attribute {string} and the value {string} should not exist'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Examples**
|
|
132
|
+
|
|
133
|
+
```gherkin
|
|
134
|
+
Then the element "a" with the attribute "href" and the value "/admin" should not exist
|
|
135
|
+
Then the element "input" with the attribute "type" and the value "hidden" should not exist
|
|
136
|
+
And the element "button" with the attribute "disabled" and the value "true" should not exist
|
|
137
|
+
Then the element "div" with the attribute "data-testid" and the value "error" should not exist
|
|
138
|
+
Then the element "img" with the attribute "alt" and the value "" should not exist
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## 6. Then the element "a" with the attribute "href" and the value containing "/old" should not exist
|
|
142
|
+
|
|
143
|
+
Assert NO element has attribute value containing a substring.
|
|
144
|
+
|
|
145
|
+
**Keyword**: `Then`
|
|
146
|
+
|
|
147
|
+
**Pattern**
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
'the element {string} with the attribute {string} and the value containing {string} should not exist'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Examples**
|
|
154
|
+
|
|
155
|
+
```gherkin
|
|
156
|
+
Then the element "a" with the attribute "href" and the value containing "/old" should not exist
|
|
157
|
+
Then the element "div" with the attribute "class" and the value containing "is-error" should not exist
|
|
158
|
+
And the element "button" with the attribute "data-testid" and the value containing "deprecated" should not exist
|
|
159
|
+
Then the element "img" with the attribute "src" and the value containing "tracking" should not exist
|
|
160
|
+
Then the element "input" with the attribute "name" and the value containing "_legacy" should not exist
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 7. Then the element "#header" should be at the top of the viewport
|
|
164
|
+
|
|
165
|
+
Assert an element is positioned within the top 100 px of the viewport.
|
|
166
|
+
|
|
167
|
+
**Keyword**: `Then`
|
|
168
|
+
|
|
169
|
+
**Pattern**
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
'the element {string} should be at the top of the viewport'
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Examples**
|
|
176
|
+
|
|
177
|
+
```gherkin
|
|
178
|
+
Then the element "#header" should be at the top of the viewport
|
|
179
|
+
Then the element "h1" should be at the top of the viewport
|
|
180
|
+
And the element ".sticky-nav" should be at the top of the viewport
|
|
181
|
+
When I scroll to the top
|
|
182
|
+
Then the element "#hero" should be at the top of the viewport
|
|
183
|
+
Then the element "[role=banner]" should be at the top of the viewport
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 8. Then the element ".hero" should be centered in the viewport
|
|
187
|
+
|
|
188
|
+
Assert an element is horizontally centered in the viewport (±10% tolerance).
|
|
189
|
+
|
|
190
|
+
**Keyword**: `Then`
|
|
191
|
+
|
|
192
|
+
**Pattern**
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
'the element {string} should be centered in the viewport'
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Examples**
|
|
199
|
+
|
|
200
|
+
```gherkin
|
|
201
|
+
Then the element ".hero" should be centered in the viewport
|
|
202
|
+
Then the element "#cta" should be centered in the viewport
|
|
203
|
+
And the element ".modal-dialog" should be centered in the viewport
|
|
204
|
+
Then the element "h1" should be centered in the viewport
|
|
205
|
+
Then the element ".loader" should be centered in the viewport
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 9. When I click on the element "#sign-in"
|
|
209
|
+
|
|
210
|
+
Click an element addressed by CSS selector.
|
|
211
|
+
|
|
212
|
+
**Keyword**: `When`
|
|
213
|
+
|
|
214
|
+
**Pattern**
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
/^(I |we )*click on the element "([^"]*)"$/
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Examples**
|
|
221
|
+
|
|
222
|
+
```gherkin
|
|
223
|
+
When I click on the element "#sign-in"
|
|
224
|
+
When I click on the element ".btn-primary"
|
|
225
|
+
And we click on the element "[data-testid=cta]"
|
|
226
|
+
When I click on the element "li.nav-item:first-child a"
|
|
227
|
+
When I click on the element "button[aria-label='Close']"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## 10. When I trigger the JS event "click" on the element "#cta"
|
|
231
|
+
|
|
232
|
+
Dispatch a synthetic JavaScript event on a CSS-addressed element.
|
|
233
|
+
|
|
234
|
+
Useful for components that listen for non-bubbling events or for events
|
|
235
|
+
Playwright cannot synthesize through normal interactions.
|
|
236
|
+
|
|
237
|
+
**Keyword**: `When`
|
|
238
|
+
|
|
239
|
+
**Pattern**
|
|
240
|
+
|
|
241
|
+
```js
|
|
242
|
+
/^(I |we )*trigger the JS event "([^"]*)" on the element "([^"]*)"$/
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Examples**
|
|
246
|
+
|
|
247
|
+
```gherkin
|
|
248
|
+
When I trigger the JS event "click" on the element "#cta"
|
|
249
|
+
When I trigger the JS event "change" on the element "#country"
|
|
250
|
+
And I trigger the JS event "input" on the element "#search"
|
|
251
|
+
When I trigger the JS event "focus" on the element "#email"
|
|
252
|
+
When I trigger the JS event "blur" on the element "#name"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## 11. When I scroll to the element "#footer"
|
|
256
|
+
|
|
257
|
+
Scroll a CSS-addressed element into view (uses Playwright's auto-scroll).
|
|
258
|
+
|
|
259
|
+
**Keyword**: `When`
|
|
260
|
+
|
|
261
|
+
**Pattern**
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
/^(I |we )*scroll to the element "([^"]*)"$/
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Examples**
|
|
268
|
+
|
|
269
|
+
```gherkin
|
|
270
|
+
When I scroll to the element "#footer"
|
|
271
|
+
When I scroll to the element ".pricing-table"
|
|
272
|
+
And we scroll to the element "[data-testid=signup-cta]"
|
|
273
|
+
When I scroll to the element "tbody tr:nth-child(20)"
|
|
274
|
+
When I scroll to the element ".testimonial:last-child"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## 12. When I hover over the element ".tooltip-trigger"
|
|
278
|
+
|
|
279
|
+
Hover the mouse pointer over a CSS-addressed element.
|
|
280
|
+
|
|
281
|
+
**Keyword**: `When`
|
|
282
|
+
|
|
283
|
+
**Pattern**
|
|
284
|
+
|
|
285
|
+
```js
|
|
286
|
+
/^(I |we )*hover over the element "([^"]*)"$/
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Examples**
|
|
290
|
+
|
|
291
|
+
```gherkin
|
|
292
|
+
When I hover over the element ".tooltip-trigger"
|
|
293
|
+
When I hover over the element "#user-menu"
|
|
294
|
+
And we hover over the element "[data-testid=avatar]"
|
|
295
|
+
When I hover over the element "img.preview"
|
|
296
|
+
When I hover over the element "li.menu-item"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## 13. When I focus on the element "#email"
|
|
300
|
+
|
|
301
|
+
Move keyboard focus to a CSS-addressed element.
|
|
302
|
+
|
|
303
|
+
**Keyword**: `When`
|
|
304
|
+
|
|
305
|
+
**Pattern**
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
/^(I |we )*focus on the element "([^"]*)"$/
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Examples**
|
|
312
|
+
|
|
313
|
+
```gherkin
|
|
314
|
+
When I focus on the element "#email"
|
|
315
|
+
When I focus on the element "input[type=search]"
|
|
316
|
+
And we focus on the element "[data-testid=combobox]"
|
|
317
|
+
When I focus on the element "textarea#message"
|
|
318
|
+
When I focus on the element "button.primary"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## 14. Then the element "#dashboard" should be displayed
|
|
322
|
+
|
|
323
|
+
Wait for a CSS-addressed element to become visible (display !== none, etc.).
|
|
324
|
+
|
|
325
|
+
**Keyword**: `Then`
|
|
326
|
+
|
|
327
|
+
**Pattern**
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
'the element {string} should be displayed'
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Examples**
|
|
334
|
+
|
|
335
|
+
```gherkin
|
|
336
|
+
Then the element "#dashboard" should be displayed
|
|
337
|
+
Then the element ".success-banner" should be displayed
|
|
338
|
+
And the element "[data-testid=user-list]" should be displayed
|
|
339
|
+
Then the element ".toast" should be displayed
|
|
340
|
+
When I press "Save"
|
|
341
|
+
Then the element ".toast-success" should be displayed
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## 15. Then the element "#loading-spinner" should not be displayed
|
|
345
|
+
|
|
346
|
+
Assert a CSS-addressed element is hidden or absent.
|
|
347
|
+
|
|
348
|
+
**Keyword**: `Then`
|
|
349
|
+
|
|
350
|
+
**Pattern**
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
'the element {string} should not be displayed'
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Examples**
|
|
357
|
+
|
|
358
|
+
```gherkin
|
|
359
|
+
Then the element "#loading-spinner" should not be displayed
|
|
360
|
+
Then the element ".error-banner" should not be displayed
|
|
361
|
+
And the element "[data-testid=skeleton]" should not be displayed
|
|
362
|
+
Then the element ".modal" should not be displayed
|
|
363
|
+
When I press "Submit"
|
|
364
|
+
Then the element ".pending-badge" should not be displayed
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## 16. Then the element "#hero" should be displayed within a viewport
|
|
368
|
+
|
|
369
|
+
Assert an element is fully inside the current viewport rectangle.
|
|
370
|
+
|
|
371
|
+
**Keyword**: `Then`
|
|
372
|
+
|
|
373
|
+
**Pattern**
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
'the element {string} should be displayed within a viewport'
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Examples**
|
|
380
|
+
|
|
381
|
+
```gherkin
|
|
382
|
+
Then the element "#hero" should be displayed within a viewport
|
|
383
|
+
Then the element ".cta" should be displayed within a viewport
|
|
384
|
+
And the element "[data-testid=summary]" should be displayed within a viewport
|
|
385
|
+
Then the element "h1" should be displayed within a viewport
|
|
386
|
+
When I scroll to the element "#footer"
|
|
387
|
+
Then the element "#footer" should be displayed within a viewport
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## 17. Then the element "#hero" should be displayed within a viewport with a top offset of 60 pixels
|
|
391
|
+
|
|
392
|
+
Assert an element is fully inside the viewport, allowing a top offset.
|
|
393
|
+
Useful for sticky headers — pass the header height as the offset.
|
|
394
|
+
|
|
395
|
+
**Keyword**: `Then`
|
|
396
|
+
|
|
397
|
+
**Pattern**
|
|
398
|
+
|
|
399
|
+
```js
|
|
400
|
+
'the element {string} should be displayed within a viewport with a top offset of {int} pixels'
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Examples**
|
|
404
|
+
|
|
405
|
+
```gherkin
|
|
406
|
+
Then the element "#hero" should be displayed within a viewport with a top offset of 60 pixels
|
|
407
|
+
Then the element ".main" should be displayed within a viewport with a top offset of 80 pixels
|
|
408
|
+
And the element ".cta" should be displayed within a viewport with a top offset of 50 pixels
|
|
409
|
+
Then the element "h1" should be displayed within a viewport with a top offset of 100 pixels
|
|
410
|
+
Then the element "#summary" should be displayed within a viewport with a top offset of 64 pixels
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## 18. Then the element "#footer" should not be displayed within a viewport with a top offset of 60 pixels
|
|
414
|
+
|
|
415
|
+
Assert an element is NOT inside the viewport (top-offset variant).
|
|
416
|
+
|
|
417
|
+
**Keyword**: `Then`
|
|
418
|
+
|
|
419
|
+
**Pattern**
|
|
420
|
+
|
|
421
|
+
```js
|
|
422
|
+
'the element {string} should not be displayed within a viewport with a top offset of {int} pixels'
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
**Examples**
|
|
426
|
+
|
|
427
|
+
```gherkin
|
|
428
|
+
Then the element "#footer" should not be displayed within a viewport with a top offset of 60 pixels
|
|
429
|
+
Then the element ".off-screen" should not be displayed within a viewport with a top offset of 80 pixels
|
|
430
|
+
And the element ".pending" should not be displayed within a viewport with a top offset of 50 pixels
|
|
431
|
+
Then the element "#cookies-banner" should not be displayed within a viewport with a top offset of 100 pixels
|
|
432
|
+
Then the element ".low-priority" should not be displayed within a viewport with a top offset of 64 pixels
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## 19. Then the element "#footer" should not be displayed within a viewport
|
|
436
|
+
|
|
437
|
+
Assert an element is NOT inside the viewport rectangle.
|
|
438
|
+
|
|
439
|
+
**Keyword**: `Then`
|
|
440
|
+
|
|
441
|
+
**Pattern**
|
|
442
|
+
|
|
443
|
+
```js
|
|
444
|
+
'the element {string} should not be displayed within a viewport'
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Examples**
|
|
448
|
+
|
|
449
|
+
```gherkin
|
|
450
|
+
Then the element "#footer" should not be displayed within a viewport
|
|
451
|
+
Then the element ".off-screen" should not be displayed within a viewport
|
|
452
|
+
And the element ".pending" should not be displayed within a viewport
|
|
453
|
+
Then the element "#cookies-banner" should not be displayed within a viewport
|
|
454
|
+
Then the element ".low-priority" should not be displayed within a viewport
|
|
455
|
+
```
|