Releases: KnowledgeExpert/selenidejs
1.4.6
1.4.5
Flatten inner lists inside have.texts(HERE)
Now you can pass nested arrays to have.texts
:
// Like:
await table.all('tr').all('td').should(
have.texts(
['Bach', 'Frank', '[email protected]'],
['Conway', 'Tim', '[email protected]'],
)
)
// Instead of:
await table.all('tr').all('td').should(
have.texts(
'Bach', 'Frank', '[email protected]',
'Conway', 'Tim', '[email protected]',
)
)
You might need this if you use formatter like prettier, that will format your code more like:
await table.all('tr').all('td').should(
have.texts(
'Bach',
'Frank',
'[email protected]',
'Conway',
'Tim',
'[email protected]',
)
)
– that is pretty not readable in context of table data...
1.4.4
Selenium 4.10.0 and new collection commands
new commands:
- collection.even
- collection.odd
- collection.sliced(start, end, STEP)
- collection.all(selector)
- collection.allFirst(selector)
new import alias:
import { command } from 'selenidejs'
- as alias to
import { perform } from 'selenidejs'
- as alias to
fix bugs:
- once
collection.should(have.texts(...))
fails,
sometimes returns unclear reason in error message:
"Cannot read properties of undefined (reading 'includes')" - have.exactText does not accept numbers
- have.exactTexts does not type hint for expected texts as numbers
upgrade selenium to 4.10.0
1.4.0
import { browser } from 'selenidejs' ;)
Here we go with even easier way to use selenidejs with prebuilt browser instance;)
/* selenidejs-demo/__tests__/google-search.test.js */
import 'chromedriver'
import { test, afterAll, beforeEach } from '@jest/globals'
import { browser, by, be, have } from 'selenidejs'
const query = browser.element(by.name('q'))
const results = browser.all('#rso>div')
const firstResultHeader = results.first.element('h3')
beforeEach(async () => {
browser.config.baseUrl = 'https://google.com'
browser.config.timeout = 2.0
browser.config.windowWidth = '1024'
browser.config.windowHeight = '768'
})
test('google finds selenidejs', async () => {
await browser.open('/ncr')
await query.should(be.blank)
await query.type('selenidejs')
await query.pressEnter()
await results.should(have.sizeGreaterThanOrEqual(6))
await results.first.should(have.text('selenidejs'))
await firstResultHeader.click()
await browser.should(have.titleContaining(
'GitHub - KnowledgeExpert/selenidejs'
))
})
afterAll(async () => {
await browser.quit()
})
1.3.6
New Features
-
now you can pass a function that returns driver to provide smarter driver management:
let globalDriver: WebDriver; // to be initialized later Browser.configuredWith() .driver(() => globalDriver) ._locationStrategy(mobile.selectorToBy) .timeout(10000) .build();
CHANGES
- update selenium from 4.1.0 to 4.3.1
1.3.4
Selenium 4.1.2 and custom location strategy
New Features
-
added Configuration._locationStrategy
to customize the conversion from string selector to By in element builders
like browser.element(selector), browser.all(selector),
element.element(selector), element.all(selector)
By default equals to built in Extensions.cssOrXpathToBy function
that is as simple as:export function cssOrXPathToBy(selector: string): By { const cssOrXPath = selector.trim(); const isXpath = (str: string) => ( str.startsWith('/') || str.startsWith('./') || str.startsWith('..') || str.startsWith('(') || str.startsWith('*/') ); return isXpath(cssOrXPath) ? by.xpath(cssOrXPath) : by.css(cssOrXPath); }
Hence you can provide any other custom conversion fn;)
For example adapt selenidejs for appium with corresponding mobile selectors,
see an example for android at github.com/automician/selenidejs-mobile-test-appium-ts-template with usage in test by link- !NOTE! The option starts with underscore dangle.
In selenidejs the underscore dangle is used as a mark of "experimental" featues
that might change in future releases.
Speaking about_locationStrategy
either its name of signature of fn value can be changed
- !NOTE! The option starts with underscore dangle.
CHANGES
- update selenium to 4.1.2
Release 1.3.1 - fix have.text condition
FIXES
- fixed
have.text
condition - it was using alwaysmatch
instead of usingmatch
orincludes
depending on passed argument
Release 1.3.0 - shadow dom, elements mapping, find by js, enhanced executeScript
New Features
executeScript
improvements:browser.executeScript(...)
andelement.executeScript(...)
- now accepts not plainstring
/Function
- but brand new ones:browser.executeScript
- now accepts(document, args, window) => ...
function, where:element.executeScript
- now accepts(element, args, window) => ...
function, where:element
- is HTMLElement which corresponds toelement
's actualWebElement
args
- is an array of passed additional arguments, likeelement.executeScript((element, args) => args[0] === 'foo' && args[1] === 'bar', 'foo', 'bar')
window
- is Window// assume dom looks like // <body> // <span>first</span> // <div> // <span>second</span> // <span>third</span> // </div> // </body> const text = await browser.executeScript(document => document.getElementsByTagName('span')[0].innerHTML); console.log(text); // 'first item' const texts = await browser.element('div').executeScript( (element, args) => { var spans = element.getElementsByTagName('span'); var textOne = spans[0].innerHTML; var textTwo = spans[1].innerHTML; return [args[0], textOne, textTwo]; }, 'first' ); console.log(texts); // ['first', 'second', 'third']
- all new arguments for
executeScript
function are typed, so if you use Typescript - you will be able to use full completion inside passed function right in your IDE
- you can now find elements not only with
string
(which is xpath or css) orBy
, but using js function also:// assume dom looks like // <body> // <span>first</span> // <div> // <span>second</span> // <span>third</span> // </div> // </body> const body = browser.element({ script: document => document.body }); const div = body.element({ script: element => element.getElementsByTagName('div')[0] }); const spans = div.all({ script: element => element.getElementsByTagName('span') }); console.log(await spans.get(their.texts)); // ['second', 'third']
- Shadow DOM support:
// assume dom looks like // <body> // ...shadowRoot... // <span>first</span> // ...shadowRoot... // </body> const span = browser.element('body').shadow.element('span'); console.log(await span.get(its.text)); // 'first'
- mapping collection elements to inner (relative) elements:
// assume dom looks like // <body> // <div> // <span>first</span> // <span>second</span> // </div> // <div> // <span>third</span> // <span>fourth</span> // </div> // </body> const firstSpans = browser.all('div').collected(it => it.element('span')); console.log(await firstSpans.get(their.texts)); // ['first', 'third'] const allSpans = browser.all('div').collected(it => it.all('span')); console.log(await allSpans.get(their.texts)); // ['first', 'second', 'third', 'fourth']
Release 1.2.1 - update selenium-webdriver dependency
1.2.1 (released on 2019.08.16)
CHANGES
- updated
selenium-webdriver
version up to4.0.0-alpha.4
The new stabilized user and test oriented API
This release includes stabilized cleaned version of API. The API for sure will be extended in future. But we will try to keep the current one stable as much as possible:)