UNPKG

13.1 kBMarkdownView Raw
1# Query and Manipulation Library
2
3[![Build Status](https://travis-ci.org/tenbits/selenium-query.png?branch=master)](https://travis-ci.org/tenbits/selenium-query)
4[![NPM version](https://badge.fury.io/js/selenium-query.svg)](http://badge.fury.io/js/selenium-query)
5[![TypeScript](https://badges.frapsoft.com/typescript/code/typescript.svg?v=101)](https://github.com/ellerbrock/typescript-badges/)
6
7#### jQuery-alike API for [Selenium WebDriver](https://seleniumhq.github.io/selenium/docs/api/javascript/index.html), [JSDom](https://github.com/jsdom/jsdom) and [Cheerio](https://github.com/cheeriojs/cheerio)
8
9
10Single API to query web-pages or html blocks with supported providers: `Selenium WebDriver`, `JSDom`, `Cheerio` _(`puppeteer` on roadmap)_.
11
12> Use for tests or crawlers.
13
14---
15
16### Asynchronous nature
17
18As 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
19
20```javascript
21let $ = require('selenium-query');
22$(driver)
23 .find('.foo')
24 .filter('input')
25 .attr('placeholder', 'Baz')
26 .val()
27 .then(value => console.log(value));
28
29// or via await
30let value = await $(driver).find('input.foo').val();
31console.log(value);
32```
33
34### Extension methods
35
36As with jQuery you can define an extension method and call it in your tests
37
38```javascript
39let $ = require('selenium-query');
40$.fn.doBaz = function(){
41 return this.each(el => {
42 // do some usefull things with WebElement/JsDomElement/CherioElement
43 });
44};
45$(driver)
46 .find('input')
47 .doBaz();
48```
49
50## API
51
52##### ☰
53- [`constructor`](#constructor)
54- [Collection](#collection)
55 - [`length`](#length)
56 - [`eq`](#eq)
57 - [`slice`](#slice)
58 - [`each`](#each)
59 - [`map`](#map)
60 - [`toArray`](#toArray)
61- [Traverse](#traverse)
62 - [`find`](#find)
63 - [`filter`](#filter)
64 - [`children`](#children)
65 - [`parent`](#parent)
66 - [`closest`](#closest)
67- [Attributes](#attributes)
68 - [`attr`](#attr)
69 - [`removeAttr`](#removeAttr)
70 - [`prop`](#prop)
71 - [`removeProp`](#removeProp)
72 - [`val`](#val)
73 - [`css`](#css)
74- [Class](#class)
75 - [`hasClass`](#hasClass)
76 - [`addClass`](#addClass)
77 - [`removeClass`](#removeAttr)
78 - [`toggleClass`](#toggleClass)
79- [Manipulate](#manipulate)
80 - [`remove`](#remove)
81- [Dimension and Position](#dimensions)
82 - [`height`](#height)
83 - [`width`](#width)
84 - [`innerHeight`](#innerHeight)
85 - [`innerWidth`](#innerWidth)
86 - [`offset`](#offset)
87 - [`position`](#position)
88 - [`scrollTop`](#scrollTop)
89 - [`scrollLeft`](#scrollLeft)
90- [Content](#content)
91 - [`html`](#html)
92 - [`text`](#text)
93 - [`append`](#append)
94 - [`prepend`](#prepend)
95 - [`before`](#before)
96 - [`after`](#after)
97- [Events](#events)
98 - [`trigger`](#trigger)
99 - [`click`](#click)
100 - [`change`](#change)
101 - [`focus`](#focus)
102 - [`blur`](#blur)
103 - :sparkles: [`type`](#type)
104 - :sparkles: [`press`](#press)
105 - :sparkles: [`sendKeys`](#sendKeys)
106 - :sparkles: [`select`](#select)
107
108- [Misc](#misc)
109 - [`eval`](#eval)
110
111- [Document](#document)
112 - [`load`](#load)
113 - [`getDriver`](#getDriver)
114 - [`setDriver`](#setDriver)
115
116- :zap: [JsDom](#jsdom)
117 - [`build`](#jsdom-build)
118 - [`load`](#jsdom-load)
119
120- :zap: [Cheerio](#cheerio)
121 - [`build`](#cheerio-build)
122 - [`load`](#cheerio-load)
123
124- :zap: [Network](#network)
125 - [`load`](#network-load)
126
127
128##### `constructor(WebDriver|WebElement|Array<WebElement>|SQuery|Array<SQuery>)` <a name='constructor'></a>
129
130- [WebDriver](https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html)
131- [WebElement](https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)
132
133```javascript
134let SQuery = require('selenium-query');
135let $document = SQuery(driver);
136let $inputs = $document.find('inputs');
137```
138
139## Collection
140
141##### `length:number` <a name='length'></a>
142Count of WebElements in a current set.
143> :exclamation: Due to asynchronous nature, sometimes you have to wait until the promise is resolved to get the correct `length` value
144
145##### `eq(index:number):SQuery` <a name='eq'></a>
146Get the SQuery instance with only one element at the index.
147> :exclamation: Once again, wait until the promise is resolved, or **chain** the manipulations
148```javascript
149$(driver)
150 .find('button')
151 .eq(0)
152 .css('background-color', 'red')
153 .done(() => console.log('The color has been changed.'))
154// instead of an equivalent
155$(driver)
156 .find('button')
157 .done(buttons => {
158 buttons
159 .eq(0)
160 .done(firstButton => {
161 firstButton
162 .css('background-color', 'red')
163 .done(() => console.log('The color has been changed.'))
164 })
165 });
166```
167
168##### `slice([start:number = 0, end:number = .length]):SQuery` <a name='slice'></a>
169Get elements range.
170
171##### `each(function<node:WebElement, index:number, Promise|void 0>):SQuery` <a name='each'></a>
172Enumerate the collection. The callback function can return a promise, if an async job is performed.
173
174##### `map(function<node:WebElement, index:number, Promise|any>):SQuery` <a name='map'></a>
175Map the collection into the new one. Return the value from the function or a promise which resolves then with the value.
176
177##### `toArray():Promise<Array<any>>` <a name='toarray'></a>
178Returns a promise which resolves with an Array instance of current elements in collection
179
180
181## Traverse
182
183##### `find(selector:string):SQuery` <a name='find'></a>
184Find element(s).
185
186##### `filter(selector:string):SQuery` <a name='filter'></a>
187Filter element(s) out of the current collection.
188
189##### `children([selector:string]):SQuery` <a name='children'></a>
190Get, and optionally filter, children of every element in the collection.
191
192##### `parent():SQuery` <a name='parent'></a>
193Get parent elements of every element in the collection
194
195##### `closest(selector):SQuery` <a name='closest'></a>
196Find ancestor of every element in the collection
197
198
199## Attributes
200
201##### `attr(key:string | key:string, val:any | attributes:Object ):SQuery|Promise<any>` <a name='attr'></a>
202Get attribute value of the first element in the collection, or set attribute(s) to each element.
203
204##### `removeAttr(key:string):SQuery` <a name='removeAttr'></a>
205Remove the attribute
206
207##### `prop(key:string | key:string, val:any | properties:Object):SQuery|Promise<any>` <a name='prop'></a>
208Get property value of the first element in the collection, or set property(ies) to each element.
209
210##### `removeProp(key:string):SQuery` <a name='removeProp'></a>
211Delete property
212
213##### `val([value:string]):SQuery` <a name='val'></a>
214Get or set `value` property, like `input.value`
215
216##### `css(key:string | key:string, val:string | css:Object ):SQuery|Promise<any>` <a name='css'></a>
217Get or set style properties
218
219## Class
220
221##### `hasClass(name:string):Promise<boolean>` <a name='hasClass'></a>
222Check if the first element has the class name.
223
224##### `addClass(name:string):SQuery` <a name='addClass'></a>
225Add the class name(s) to every element in the collection
226
227##### `removeClass(name:string):SQuery` <a name='removeClass'></a>
228Remove the class name(s) of every element in the collection
229
230##### `toggleClass(name:string):SQuery` <a name='toggleClass'></a>
231Toggle the class name(s) of every element in the collection
232
233## Manipulate
234
235##### `remove():SQuery` <a name='remove'></a>
236Remove the elements from the parent nodes
237
238## Dimensions
239
240##### `height():Promise<number>` <a name='height'></a>
241##### `width():Promise<number>` <a name='width'></a>
242##### `innerHeight():Promise<number>` <a name='innerHeight'></a>
243##### `innerWidth():Promise<number>` <a name='innerWidth'></a>
244##### `offset():Promise<object{top,left}>` <a name='offset'></a>
245##### `position():Promise<object{top,left}>` <a name='position'></a>
246##### `scrollTop():Promise<number>` <a name='scrollTop'></a>
247##### `scrollLeft():Promise<number>` <a name='scrollLeft'></a>
248
249## Content
250
251##### `html([html:string]):SQuery|Promise<string>` <a name='html'></a>
252##### `text([text:string]):SQuery|Promise<string>` <a name='text'></a>
253
254##### `append(html:string):SQuery` <a name='append'></a>
255##### `prepend(html:string):SQuery` <a name='prepend'></a>
256##### `before(html:string):SQuery` <a name='before'></a>
257##### `after(html:string):SQuery` <a name='after'></a>
258
259## Events
260
261##### `trigger(type:string [, data:Object]):SQuery` <a name='trigger'></a>
262Trigger native or custom event.
263
264##### `click():SQuery` <a name='click'></a>
265##### `change():SQuery` <a name='change'></a>
266Trigger `change` event
267##### `focus():SQuery` <a name='click'></a>
268##### `blur():SQuery` <a name='click'></a>
269
270##### `type(text:string):SQuery` <a name='type'></a>
271Enter the text.
272> :exclamation: Meta keys are supported in `{}`
273
274##### `press(combination:string):SQuery` <a name='press'></a>
275Press key combination. E.g.: `ctrl+c`, `a+b+c`, `ctrl+alt+d`, `ctrl++` _(`control` and `plus` keys)_
276
277##### `sendKeys(text:string):SQuery` <a name='sendKeys'></a>
278Call native Selenums `sendKeys` fn on each element
279
280##### `select(text:string | start:number[, end:number]):SQuery` <a name='select'></a>
281Select an option from the `select` element, or if the `input` the selects a text or range
282
283
284## Misc
285
286##### `eval(fn:Function, ...args):Promise<any>` <a name='eval'></a>
287Evaluate function in Browser.
288> :exclamation: The first argument is the first element in the set
289```javascript
290$(driver)
291 .find('button')
292 .eval(function(el){
293 // browser context
294 // do smth. with the Element and return a value
295 });
296```
297
298
299## Document
300
301#### `static` `load(url:string[, config:WebDriverOptions]):SQuery` <a name='load'></a>
302Create or reuse a WebDriver, and load the page.
303
304#### `WebDriverOptions` defaults
305```javascript
306{
307 name: 'Chrome',
308 args: ['no-sandbox'],
309 binaryPath: null,
310
311 // For better control and to change the behaviour of how the options are created and applied,
312 // you can define next functions
313 applyOptions: function(builder, options) {},
314 setOptions (builder, options) {},
315 setArguments (options) {},
316 setBinaryPath (options) {},
317 setLogging (options) {}
318}
319```
320
321## JsDom
322
323#### `static` `SQuery.jsdom.build(config: IJsdomParams):SQuery` <a name='jsdom-build'></a>
324
325```typescript
326interface IJsdomParams {
327 html: string
328}
329```
330
331Create SQuery collection with JsDom driver
332
333#### `static` `SQuery.jsdom.load(url: string, config: IJsdomLoadParams):SQuery` <a name='jsdom-load'></a>
334
335```typescript
336interface IJsdomLoadParams {
337 headers?: {[name: string] : string }
338 method?
339 query?: {[name: string] : string }
340 payload?
341 cookies?: string | string[]
342 cache?: {
343 folder?: string
344 maxAge?: number
345 }
346 cacheQueryIgnore?: string[]
347 /** Webdriver will load this url, or requested url, to set the cookies first */
348 cookieOrigin?: string
349}
350```
351
352## Cheerio
353
354#### `static` `SQuery.cheerio.build(config: ICheerioParams):SQuery` <a name='cheerio-build'></a>
355
356```typescript
357interface ICheerioParams {
358 html: string
359}
360```
361
362Create SQuery collection with Cheerio driver (_Only query and manipulation methods are implemented_)
363
364#### `static` `SQuery.cheerio.load(url: string, config: ICheerioLoadParams):SQuery` <a name='cheerio-load'></a>
365
366```typescript
367interface ICheerioLoadParams {
368 headers?: {[name: string] : string }
369 method?
370 query?: {[name: string] : string }
371 payload?
372 cookies?: string | string[]
373 cache?: {
374 folder?: string
375 maxAge?: number
376 }
377 cacheQueryIgnore?: string[]
378 /** Webdriver will load this url, or requested url, to set the cookies first */
379 cookieOrigin?: string
380}
381```
382
383
384
385## Network
386
387HTTP Utils to load and submit data. Handles cache and cookies.
388
389#### `load` `SQuery.network.load(url: string, config: IHttpParams):IHttpResponse` <a name='network-load'></a>
390
391```typescript
392interface IHttpParams {
393 headers?: {[name: string] : string }
394 method?: 'post' | 'get' | 'delete' | 'patch' | 'head' | string
395 query?: {[name: string] : string }
396 body?: string | Buffer
397
398 cookies?: {[name: string] : string } | string[] | string
399 cookiesDefault?: {[name: string] : string } | string[] | string
400
401 cache?: boolean | {
402 folder?: string
403 maxAge?: number
404 compress?: boolean
405 //-ensureCacheAllowed? (resp): boolean
406 }
407 cacheQueryIgnore?: string[]
408
409 retryCount?: number
410 retryTimeout?: number
411 follow?: number
412 httpsProxy?: string
413 ignoreSSLErrors?: boolean
414}
415interface IHttpResponse {
416 status: number
417 message?: string
418
419 headers: {[name: string] : string }
420 url: string
421 body: any
422}
423```
424
425
426**Example**
427```javascript
428$
429 .load('http://google.com')
430 .find('input')
431 .css('background-color', 'red');
432```
433
434
435:checkered_flag:
436
437---
438
439:copyright: MIT, Alex Kit