selenium-query v0.52.76
Web Query and Manipulation Library
jQuery-alike API for Selenium WebDriver, JSDom and Cheerio
Single API to query web-pages or html blocks with supported providers: Selenium WebDriver
, JSDom
, Cheerio
, Plain-HTTP
.
Use for tests, crawlers and automations.
Request
All cookies received from the backend will be reused for a domain.
import SQuery from 'selenium-query';
let $ = await SQuery.load(url, config?: IConfig)
Query and Manipulate
Asynchronous nature
As the WebDriver methods are async, Selenium Query
instance implements Promise
and you can chain the function calls or use async/await
. A very basic example
import $ from 'selenium-query';
$(driver)
.find('.foo')
.filter('input')
.attr('placeholder', 'Baz')
.val()
.then(value => console.log(value));
// or via await
let value = await $(driver).find('input.foo').val();
console.log(value);
Extension methods
As with jQuery you can define an extension method and call it in your tests
import $ from 'selenium-query';
$.fn.doBaz = function(){
return this.each(el => {
// do some usefull things with WebElement/JsDomElement/CherioElement
});
};
$(driver)
.find('input')
.doBaz();
WebDriver network monitor
Allows to get and to listen for events emitted by the browser
import { BrowserNetworkMonitor } from 'selenium-query';
let monitor = await BrowserNetworkMonitor.start(driver);
monitor
.on('requestWillBeSent', req => console.log(req))
.on('responseReceived', req => console.log(req))
.on('loadingFinished', req => console.log(req));
// ... e.g. after the a page is loaded
let { request, response } = monitor.getRequest(/index.html/);
console.log(request.headers, response.headers);
// get the response body
let { base64Encoded, body } = monitor.getResponseBody(mainPageRequest);
WebDriver network interceptor
Allows to send custom responses for requests back to the browser
import { BrowserNetworkInterceptor } from 'selenium-query';
let interceptor = await BrowserNetworkInterceptor.start(driver);
interceptor.register({
match: /index.html/,
response: {
status: 200,
headers: {
'Content-Type': 'text/html'
},
body: '<!DOCTYPE html> <h1>Changed</h1>'
}
});
// ... load index.html, and the modified content should be loaded
Pseudo selectors
:text
and improved :has
selectors
let html = `
<ul>
<li name='x'>Foo <span id='foo'></span></li>
<li name='y'>Bar <span id='bar'></span></li>
</ul>
`;
SQuery.pseudo.isBar = async ($el, innerQuery) => {
let $children = await $el.find('#bar');
return $children.length > 0;
};
let value1 = await $.find('li:text(Bar)').attr('name');
let value2 = await $.find('li:has(span#id)').attr('name');
let value3 = await $.find('li:isBar()').attr('name');
// value1 === value2 === value3 === 'y'
API
☰
constructor
- Collection
- Traverse
- Attributes
- Class
- Manipulate
- Dimension and Position
- Content
:zap: JsDom
:zap: Cheerio
:zap: Network
constructor(WebDriver|WebElement|Array<WebElement>|SQuery|Array<SQuery>)
let SQuery = require('selenium-query');
let $document = SQuery(driver);
let $inputs = $document.find('inputs');
Collection
length:number
Count of WebElements in a current set.
:exclamation: Due to asynchronous nature, sometimes you have to wait until the promise is resolved to get the correct
length
value
eq(index:number):SQuery
Get the SQuery instance with only one element at the index.
:exclamation: Once again, wait until the promise is resolved, or chain the manipulations
await $(driver) .find('button') .eq(0) .css('background-color', 'red') // instead of an equivalent
let buttons = await $(driver).find('button') let firstButton = await buttons.eq(0);
await firstButton.css('background-color', 'red'); console.log('The color has been changed.'));
##### `slice([start:number = 0, end:number = .length]):SQuery` <a name='slice'></a>
Get elements range.
##### `each(function<node:WebElement, index:number, Promise|void 0>):SQuery` <a name='each'></a>
Enumerate the collection. The callback function can return a promise, if an async job is performed.
##### `map(function<node:WebElement, index:number, Promise|any>):SQuery` <a name='map'></a>
Map the collection into the new one. Return the value from the function or a promise which resolves then with the value.
##### `toArray():Promise<Array<any>>` <a name='toarray'></a>
Returns a promise which resolves with an Array instance of current elements in collection
## Traverse
##### `find(selector:string):SQuery` <a name='find'></a>
Find element(s).
##### `filter(selector:string):SQuery` <a name='filter'></a>
Filter element(s) out of the current collection.
##### `children([selector:string]):SQuery` <a name='children'></a>
Get, and optionally filter, children of every element in the collection.
##### `parent():SQuery` <a name='parent'></a>
Get parent elements of every element in the collection
##### `closest(selector):SQuery` <a name='closest'></a>
Find ancestor of every element in the collection
## Attributes
##### `attr(key:string | key:string, val:any | attributes:Object ):SQuery|Promise<any>` <a name='attr'></a>
Get attribute value of the first element in the collection, or set attribute(s) to each element.
##### `removeAttr(key:string):SQuery` <a name='removeAttr'></a>
Remove the attribute
##### `prop(key:string | key:string, val:any | properties:Object):SQuery|Promise<any>` <a name='prop'></a>
Get property value of the first element in the collection, or set property(ies) to each element.
##### `removeProp(key:string):SQuery` <a name='removeProp'></a>
Delete property
##### `val([value:string]):SQuery` <a name='val'></a>
Get or set `value` property, like `input.value`
##### `css(key:string | key:string, val:string | css:Object ):SQuery|Promise<any>` <a name='css'></a>
Get or set style properties
## Class
##### `hasClass(name:string):Promise<boolean>` <a name='hasClass'></a>
Check if the first element has the class name.
##### `addClass(name:string):SQuery` <a name='addClass'></a>
Add the class name(s) to every element in the collection
##### `removeClass(name:string):SQuery` <a name='removeClass'></a>
Remove the class name(s) of every element in the collection
##### `toggleClass(name:string):SQuery` <a name='toggleClass'></a>
Toggle the class name(s) of every element in the collection
## Manipulate
##### `remove():SQuery` <a name='remove'></a>
Remove the elements from the parent nodes
## Dimensions
##### `height():Promise<number>` <a name='height'></a>
##### `width():Promise<number>` <a name='width'></a>
##### `innerHeight():Promise<number>` <a name='innerHeight'></a>
##### `innerWidth():Promise<number>` <a name='innerWidth'></a>
##### `offset():Promise<object{top,left}>` <a name='offset'></a>
##### `position():Promise<object{top,left}>` <a name='position'></a>
##### `scrollTop():Promise<number>` <a name='scrollTop'></a>
##### `scrollLeft():Promise<number>` <a name='scrollLeft'></a>
## Content
##### `html([html:string]):SQuery|Promise<string>` <a name='html'></a>
##### `text([text:string]):SQuery|Promise<string>` <a name='text'></a>
##### `append(html:string):SQuery` <a name='append'></a>
##### `prepend(html:string):SQuery` <a name='prepend'></a>
##### `before(html:string):SQuery` <a name='before'></a>
##### `after(html:string):SQuery` <a name='after'></a>
## Events
##### `trigger(type:string [, data:Object]):SQuery` <a name='trigger'></a>
Trigger native or custom event.
##### `click():SQuery` <a name='click'></a>
##### `change():SQuery` <a name='change'></a>
Trigger `change` event
##### `focus():SQuery` <a name='click'></a>
##### `blur():SQuery` <a name='click'></a>
##### `type(text:string):SQuery` <a name='type'></a>
Enter the text.
> :exclamation: Meta keys are supported in `{}`
##### `press(combination:string):SQuery` <a name='press'></a>
Press key combination. E.g.: `ctrl+c`, `a+b+c`, `ctrl+alt+d`, `ctrl++` _(`control` and `plus` keys)_
##### `sendKeys(text:string):SQuery` <a name='sendKeys'></a>
Call native Selenums `sendKeys` fn on each element
##### `select(text:string | start:number[, end:number]):SQuery` <a name='select'></a>
Select an option from the `select` element, or if the `input` the selects a text or range
## Misc
##### `eval(fn:Function, ...args):Promise<any>` <a name='eval'></a>
Evaluate function in Browser.
> :exclamation: The first argument is the first element in the set
```typescript
let result = await $(driver)
.find('button')
.eval((el: HTMLButton) => {
// browser context
// do smth. with the Element and return a value
return el.tagName;
});
Document
static
load(url:string[, config:WebDriverOptions]):SQuery
Create or reuse a WebDriver, and load the page.
WebDriverOptions
defaults
{
name: 'Chrome',
args: ['no-sandbox'],
binaryPath: null,
// For better control and to change the behaviour of how the options are created and applied,
// you can define next functions
applyOptions: function(builder, options) {},
setOptions (builder, options) {},
setArguments (options) {},
setBinaryPath (options) {},
setLogging (options) {}
}
JsDom
static
SQuery.jsdom.build(config: IJsdomParams):SQuery
interface IJsdomParams {
html: string
}
Create SQuery collection with JsDom driver
static
SQuery.jsdom.load(url: string, config: IJsdomLoadParams):SQuery
interface IJsdomLoadParams {
headers?: {[name: string] : string }
method?
query?: {[name: string] : string }
payload?
cookies?: string | string[]
cache?: {
folder?: string
maxAge?: number
}
cacheQueryIgnore?: string[]
/** Webdriver will load this url, or requested url, to set the cookies first */
cookieOrigin?: string
}
Cheerio
static
SQuery.cheerio.build(config: ICheerioParams):SQuery
interface ICheerioParams {
html: string
}
Create SQuery collection with Cheerio driver (Only query and manipulation methods are implemented)
static
SQuery.cheerio.load(url: string, config: ICheerioLoadParams):SQuery
interface ICheerioLoadParams {
headers?: {[name: string] : string }
method?
query?: {[name: string] : string }
payload?
cookies?: string | string[]
cache?: {
folder?: string
maxAge?: number
}
cacheQueryIgnore?: string[]
/** Webdriver will load this url, or requested url, to set the cookies first */
cookieOrigin?: string
}
Network
HTTP Utils to load and submit data. Handles cache and cookies.
load
SQuery.network.load(url: string, config: IHttpParams):IHttpResponse
interface IHttpParams {
headers?: {[name: string] : string }
method?: 'post' | 'get' | 'delete' | 'patch' | 'head' | string
query?: {[name: string] : string }
body?: string | Buffer
cookies?: {[name: string] : string } | string[] | string
cookiesDefault?: {[name: string] : string } | string[] | string
cache?: boolean | {
folder?: string
maxAge?: number
compress?: boolean
//-ensureCacheAllowed? (resp): boolean
}
cacheQueryIgnore?: string[]
retryCount?: number
retryTimeout?: number
follow?: number
httpsProxy?: string
ignoreSSLErrors?: boolean
}
interface IHttpResponse {
status: number
message?: string
headers: {[name: string] : string }
url: string
body: any
}
Example
$
.load('http://google.com')
.find('input')
.css('background-color', 'red');
Known "features"
This version of ChromeDriver only supports Chrome version XYZ
Means the installed version of the Chromedriver is not compatible with Chrome itself. Usually it doesn't required one-to-one version, means you can use v97 of the chrome driver, with Chrome v98.
All platforms: Download the required Chromedriver from https://chromedriver.chromium.org/downloads
Windows: choco upgrade chromedriver
Stale element not found
When creating HTML DOM Elements in Chrome, make sure they are attached to the DOM
before returning them to the nodejs
process.
:checkered_flag:
:copyright: MIT, Alex Kit
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago