Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ability to test focus states #1176

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ onReadyScript // After the above conditions are met -- use this scrip
keyPressSelectors // Takes array of selector and string values -- simulates multiple sequential keypress interactions.
hoverSelector // Move the pointer over the specified DOM element prior to screen shot.
hoverSelectors // *Puppeteer only* takes array of selectors -- simulates multiple sequential hover interactions.
focusSelector // Focus the specified DOM element prior to screen shot.
focusSelectors // *Puppeteer only* takes array of selectors -- simulates multiple sequential focus interactions.
clickSelector // Click the specified DOM element prior to screen shot.
clickSelectors // *Puppeteer only* takes array of selectors -- simulates multiple sequential click interactions.
postInteractionWait // Wait for a selector after interacting with hoverSelector or clickSelector (optionally accepts wait time in ms. Idea for use with a click or hover element transition. available with default onReadyScript)
postInteractionWait // Wait for a selector after interacting with hoverSelector, clickSelector, or focusSelector (optionally accepts wait time in ms. Idea for use with a click or hover element transition. available with default onReadyScript)
scrollToSelector // Scrolls the specified DOM element into view prior to screen shot (available with default onReadyScript)
selectors // Array of selectors to capture. Defaults to document if omitted. Use "viewport" to capture the viewport size. See Targeting elements in the next section for more info...
selectorExpansion // See Targeting elements in the next section for more info...
Expand All @@ -181,20 +183,22 @@ viewports // An array of screen size objects your DOM will be tes
```


### Testing click and hover interactions
### Testing click, hover, and focus interactions
BackstopJS ships with an onReady script that enables the following interaction selectors...
```js
clickSelector: ".my-hamburger-menu",
hoverSelector: ".my-hamburger-menu .some-menu-item",
focusSelector: ".my-hamburger-menu .some-menu-item",
```
The above would tell BackstopJS to wait for your app to generate an element with a `.my-hamburger-menu` class, then click that selector. Then it would wait again for a `.my-hamburger-menu .some-menu-item` class, then move the cursor over that element (causing a hover state). Then BackstopJS would take a screenshot.
The above would tell BackstopJS to wait for your app to generate an element with a `.my-hamburger-menu` class, then click that selector. Then it would wait again for a `.my-hamburger-menu .some-menu-item` class, then move the cursor over that element (causing a hover state), then focus that element (causing a focus state). Then BackstopJS would take a screenshot.

You can use these properties independent of each other to easily test various click and or hover states in your app. These are obviously simple scenarios -- if you have more complex needs then this example should serve as a pretty good starting point create your own onReady scripts.

NOTE: Puppeteer version optionally takes `clickSelectors` & `hoverSelectors` as arrays of selectors...
NOTE: Puppeteer version optionally takes `clickSelectors`, `hoverSelectors`, and `focusSelectors` as arrays of selectors...
```js
clickSelectors: [".my-hamburger-menu",".my-hamburger-item"],
hoverSelectors: [".my-nav-menu-item",".my-nav-menu-dropdown-item"],
focusSelectors: [".my-nav-menu-item",".my-nav-menu-dropdown-item"],
```

### Key Press interactions
Expand Down
1 change: 1 addition & 0 deletions capture/config.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"focusSelector": "",
"clickSelector": "",
"postInteractionWait": 0,
"selectors": [],
Expand Down
7 changes: 7 additions & 0 deletions capture/engine_scripts/chromy/clickAndHoverHelper.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = function (chromy, scenario) {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
const scrollToSelector = scenario.scrollToSelectors || scenario.scrollToSelector;
Expand All @@ -22,6 +23,12 @@ module.exports = function (chromy, scenario) {
});
}

if (focusSelector) {
chromy
.wait(focusSelector)
.focus(focusSelector);
}

if (clickSelector) {
chromy
.wait(clickSelector)
Expand Down
8 changes: 8 additions & 0 deletions capture/engine_scripts/puppet/clickAndHoverHelper.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = async (page, scenario) => {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
const scrollToSelector = scenario.scrollToSelector;
Expand All @@ -19,6 +20,13 @@ module.exports = async (page, scenario) => {
}
}

if (focusSelector) {
for (const focusSelectorIndex of [].concat(focusSelector)) {
await page.waitFor(focusSelectorIndex);
await page.focus(focusSelectorIndex);
}
}

if (clickSelector) {
for (const clickSelectorIndex of [].concat(clickSelector)) {
await page.waitFor(clickSelectorIndex);
Expand Down
1 change: 1 addition & 0 deletions examples/Jenkins/Sample/backstop.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"focusSelector": "",
"clickSelector": "",
"postInteractionWait": 1000,
"selectors": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = async (page, scenario) => {
const hoverSelector = scenario.hoverSelector;
const focusSelector = scenario.focusSelector;
const clickSelector = scenario.clickSelector;
const postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]

Expand All @@ -8,6 +9,11 @@ module.exports = async (page, scenario) => {
await page.hover(hoverSelector);
}

if (focusSelector) {
garris marked this conversation as resolved.
Show resolved Hide resolved
await page.waitFor(focusSelector);
await page.focus(focusSelector);
}

if (clickSelector) {
await page.waitFor(clickSelector);
await page.click(clickSelector);
Expand Down
1 change: 1 addition & 0 deletions examples/responsiveDemo/backstop.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"focusSelector": "",
"clickSelector": "",
"postInteractionWait": 0,
"selectors": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = function (chromy, scenario) {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const scrollToSelector = scenario.scrollToSelectors || scenario.scrollToSelector;
const postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]
Expand All @@ -13,6 +14,12 @@ module.exports = function (chromy, scenario) {
});
}

if (focusSelector) {
chromy
.wait(focusSelector)
.focus(focusSelector);
}

if (clickSelector) {
chromy
.wait(clickSelector)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = async (page, scenario) => {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const scrollToSelector = scenario.scrollToSelector;
const postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]
Expand All @@ -11,6 +12,13 @@ module.exports = async (page, scenario) => {
}
}

if (focusSelector) {
for (const focusSelectorIndex of [].concat(focusSelector)) {
await page.waitFor(focusSelectorIndex);
await page.focus(focusSelectorIndex);
}
}

if (clickSelector) {
for (const clickSelectorIndex of [].concat(clickSelector)) {
await page.waitFor(clickSelectorIndex);
Expand Down
1 change: 1 addition & 0 deletions test/configs/backstop.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"hideSelectors": [],
"removeSelectors": [],
"hoverSelector": "",
"focusSelector": "",
"clickSelector": "",
"postInteractionWait": 0,
"selectors": [],
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = function (chromy, scenario) {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
const scrollToSelector = scenario.scrollToSelectors || scenario.scrollToSelector;
Expand All @@ -22,6 +23,12 @@ module.exports = function (chromy, scenario) {
});
}

if (focusSelector) {
chromy
.wait(focusSelector)
.focus(focusSelector);
}

if (clickSelector) {
chromy
.wait(clickSelector)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = async (page, scenario) => {
const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
const focusSelector = scenario.focusSelectors || scenario.focusSelector;
const clickSelector = scenario.clickSelectors || scenario.clickSelector;
const keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
const scrollToSelector = scenario.scrollToSelector;
Expand All @@ -17,6 +18,11 @@ module.exports = async (page, scenario) => {
await page.hover(hoverSelector);
}

if (focusSelector) {
await page.waitFor(focusSelector);
await page.focus(focusSelector);
}

if (clickSelector) {
await page.waitFor(clickSelector);
await page.click(clickSelector);
Expand Down
Loading