-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add usage to README and default timeout to API
- Loading branch information
0 parents
commit b10b131
Showing
9 changed files
with
679 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.idea/ | ||
node_modules/ |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Gideon Pyzer / Huddle | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
# puppeteer-extensions | ||
This library exposes a number of convenience functions to extend Puppeteer's API, in order to make writing tests easier. | ||
The idea is that many of these functions (or similar ones) will eventually make their way into Puppeteer's own API, but | ||
this allows us to experiment with new ways of improving UI testing. | ||
|
||
## Usage | ||
- `page` Puppeteer page instance | ||
- `timeout` [Optional] Timeout for waits in milliseconds (default: 5000 ms) | ||
|
||
```javascript | ||
const extensions = require('puppeteer-extensions')(page); | ||
``` | ||
|
||
```javascript | ||
(async() { | ||
const listItem = '.todo-list li'; | ||
... | ||
await page.extensions.waitForNthSelectorAttributeValue(listItem, 1, 'class', 'completed'); | ||
})(); | ||
|
||
``` | ||
|
||
|
||
## API | ||
The API is split into categories to better organise the extension functions. This currently includes: | ||
|
||
- [Waits](#waits) | ||
- [Retrieval](#retrieval) | ||
- [Miscellaneous](#miscellaneous) | ||
|
||
|
||
**resetRequests()** | ||
|
||
Resets the requests cache used by the `waits` API. This should be called when you are going to navigate to another page, | ||
in order to track the new requests correctly. | ||
|
||
## Waits | ||
**waitForResource(resource, timeout=defaultTimeout)** | ||
- `resource` \<string> The URL of the resource (or a substring of it) | ||
- `timeout` \<number> Timeout for the check | ||
|
||
Wait for a resource request to be responded to | ||
|
||
|
||
**waitForLoadedWebFontCountToBe(count, timeout=defaultTimeout)** | ||
- `count` \<number> The number of web fonts to expect | ||
- `timeout` \<number> Timeout for the check | ||
|
||
Wait for a specific number of web fonts to be loaded and ready on the page | ||
|
||
|
||
**waitForFunction(fn, options, ...args)** | ||
- `fn` \<function> The function to execute on the page | ||
- `options` \<object> Optional waiting parameters | ||
- `args` \<...args> Arguments to be passed into the function | ||
|
||
Wait for function to execute on the page (see [waitForFunction](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforfunctionpagefunction-options-args)) | ||
|
||
|
||
**waitForSelector(selector, timeout=defaultTimeout)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `timeout` \<number> Timeout for the check | ||
|
||
Wait for element with a given selector to exist on the page (see [waitForSelector](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforselectorselector-options)) | ||
|
||
|
||
**waitUntilExistsAndVisible(selector)** | ||
- `selector` \<string> The selector for the element on the page | ||
|
||
Wait until an element exists on the page and is visible (i.e. not transparent) (see [waitForSelector](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforselectorselector-options)) | ||
|
||
|
||
**waitWhileExistsAndVisible(selector)** | ||
- `selector` \<string> The selector for the element on the page | ||
|
||
Wait while an element still exists on the page and is visible (i.e. not transparent) (see [waitForSelector](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforselectorselector-options)) | ||
|
||
|
||
**waitUntilSelectorHasVisibleContent(selector)** | ||
- `selector` \<string> The selector for the element on the page | ||
|
||
Wait until the selector has visible content (i.e. the element takes up some width and height on the page) (i.e. not transparent) | ||
|
||
|
||
**waitWhileSelectorHasVisibleContent(selector)** | ||
- `selector` \<string> The selector for the element on the page | ||
|
||
Wait while the selector has visible content (i.e. the element takes up some width and height on the page) (i.e. not transparent) | ||
|
||
|
||
**waitForNthSelectorAttribute(selector, nth, attributeName)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `nth` \<number> The nth element found by the selector | ||
- `attributeName` \<string> The attribute name to look for | ||
|
||
Wait for the nth element found from the selector has a particular attribute | ||
|
||
|
||
**waitForSelectorAttribute(selector, attributeName)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `attributeName` \<string> The attribute name to look for | ||
|
||
Wait for the element found from the selector has a particular attribute | ||
|
||
|
||
**waitForNthSelectorAttributeValue(selector, nth, attributeName, attributeValue)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `nth` \<number> The nth element found by the selector | ||
- `attributeName` \<string> The attribute name to look for | ||
- `attributeValue` \<string> The attribute value to match the attributeName | ||
|
||
Wait for the nth element found from the selector has a particular attribute value pair | ||
|
||
|
||
**waitForSelectorAttributeValue(selector, attributeName, attributeValue)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `attributeName` \<string> The attribute name to look for | ||
- `attributeValue` \<string> The attribute value to match the attributeName | ||
|
||
Wait for the element found from the selector has a particular attribute value pair | ||
|
||
|
||
**waitForElementCount(selector, expectedCount)** | ||
- `selector` \<string> The selector for the element on the page | ||
- `expectedCount` \<number> The number of elements to expect | ||
|
||
Wait for the element count to be a particular value | ||
|
||
|
||
**waitForUrl(regex)** | ||
- `regex` \<RegExp> The regular expression to match the URL on | ||
|
||
Wait for the current window location to match a particular regular expression | ||
|
||
|
||
**waitFor(milliseconds)** | ||
- `milliseconds` \<number> The number of milliseconds to wait for | ||
|
||
Wait for a given number of milliseconds | ||
|
||
|
||
## Retrieval | ||
|
||
**getValue(selector)** | ||
- `selector` \<string> The selector for the element to get the value for | ||
- **returns** \<string> The value property value for the element | ||
|
||
Get the value property value for a particular element | ||
|
||
|
||
**getText(selector)** | ||
- `selector` \<string> The selector for the element to get the text for | ||
- **returns** \<string> The text property value for the element | ||
|
||
Get the text property value for a particular element | ||
|
||
|
||
**getPropertyValue(selector, property)** | ||
- `selector` \<string> The selector for the element to get the property value for | ||
- `property` \<string> The property to look for | ||
- **returns** \<string> The property value for the element | ||
|
||
Get the value of a particular property for a particular element | ||
|
||
|
||
**isElementFocused(selector)** | ||
- `selector` \<string> The selector of the element to check for focus state | ||
- **returns** \<boolean> Whether the element is focused or not | ||
|
||
Check if element is focused | ||
|
||
## Miscellaneous | ||
|
||
**turnOffAnimations()** | ||
|
||
Turn off CSS animations on the page to help avoid flaky visual comparisons | ||
|
||
|
||
**evaluate(fn, ...args)** | ||
- `fn` \<function> The function to execute on the page | ||
- `args` \<...args> Arguments to be passed into the function | ||
|
||
Runs a function on the page |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* | ||
* This file represents the miscellaneous API. It exposes functions that don't fit under a particular category. | ||
* | ||
**/ | ||
|
||
const serializeFunctionWithArgs = require('../external/serialization-utils'); | ||
|
||
module.exports = puppeteerPage => ({ | ||
/** | ||
* Turn off CSS animations on the page to help avoid flaky visual comparisons | ||
*/ | ||
async turnOffAnimations () { | ||
return puppeteerPage.evaluate(() => { | ||
function disableAnimations() { | ||
const {jQuery} = window; | ||
if (jQuery) { | ||
jQuery.fx.off = true; | ||
} | ||
|
||
const css = document.createElement('style'); | ||
css.type = 'text/css'; | ||
css.innerHTML = '* { -webkit-transition: none !important; transition: none !important; -webkit-animation: none !important; animation: none !important; }'; | ||
document.body.appendChild( css ); | ||
} | ||
|
||
if (document.readyState !== 'loading') { | ||
disableAnimations(); | ||
} else { | ||
window.addEventListener('load', disableAnimations, false); | ||
} | ||
}) | ||
}, | ||
/** | ||
* Run a function on the page | ||
* @param {function} fn - The function to execute on the page | ||
* @param {...args} args - Arguments to be passed into the function | ||
*/ | ||
async evaluate(fn, ...args) { | ||
const fnStr = serializeFunctionWithArgs(fn, ...args); | ||
return puppeteerPage.evaluate(fnStr); | ||
}, | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* | ||
* This file represents the retrieval API. It exposes convenience functions for getting properties/values/state from the UI. | ||
* | ||
**/ | ||
|
||
module.exports = puppeteerPage => ({ | ||
/** | ||
* Get the value property value for a particular element | ||
* @param {string} selector - The selector for the element to get the value for | ||
* @returns {string} value - The value property value for the element | ||
*/ | ||
async getValue(selector) { | ||
return puppeteerPage.evaluate(selector => { | ||
return document.querySelector(selector).value; | ||
}, selector); | ||
}, | ||
/** | ||
* Get the text property value for a particular element | ||
* @param {string} selector - The selector for the element to get the text for | ||
* @returns {string} value - The text property value for the element | ||
*/ | ||
async getText(selector) { | ||
return puppeteerPage.evaluate(selector => { | ||
return document.querySelector(selector).textContent; | ||
}, selector); | ||
}, | ||
/** | ||
* Get the value of a particular property for a particular element | ||
* @param {string} selector - The selector for the element to get the property value for | ||
* @param {string} property - The property to look for | ||
* @returns {string} value - The property value for the element | ||
*/ | ||
async getPropertyValue(selector, property) { | ||
try { | ||
return puppeteerPage.evaluate((selector, property) => { | ||
const element = document.querySelector(selector); | ||
return element[property]; | ||
}, selector, property); | ||
} catch(e) { | ||
throw Error(`Unable able to get ${property} from ${selector}.`, e); | ||
} | ||
}, | ||
/** | ||
* Check if element is focused | ||
* @param {string} selector - The selector of the element to check for focus state | ||
* @returns {boolean} Whether the element is focused or not | ||
*/ | ||
async isElementFocused (selector) { | ||
return puppeteerPage.evaluate(selector => { | ||
const element = document.querySelector(selector); | ||
return element === document.activeElement; | ||
}, selector); | ||
}, | ||
}); |
Oops, something went wrong.