Selenium/Explanation/Stack
Code from this page is available at mediawiki/core and gerrit:675850. |
This page explains stack from Selenium/Getting Started/Create a simple test page.
This tutorial will assume that you are running tests from your machine, targeting MediaWiki-Docker. For more examples see Selenium/Reference/Example Code.
Examples will:
- open browser
- go to main page
- check that
Log inlink is present - close browser
WebdriverIO
[edit]Reasons for selecting WebdriverIO:
- sane and understandable API,
- centralized and complete documentation,
- built-in page object support,
- configuration management,
- good support.
Stack
[edit]For more information about the stack see Selenium/Reference/Stack.
| Language | JavaScript/Node.js |
| Browser | Chrome |
| Selenium/WebDriver | WebdriverIO (web, API, package) |
| Testing framework | N/A |
| Assertion library | N/A |
| Page object | N/A |
Advantages
[edit]- Minimal stack.
Disadvantages
[edit]- No assertions.
- No testing framework (setup, teardown, reporting...).
- No page object pattern.
Code
[edit]tests/selenium/docs/Stack/webdriverio.js
// baseUrl is required for our continuous integration.
// If you don't have MW_SERVER and MW_SCRIPT_PATH environment variables set
// you can probably hardcode it to something like this:
// const baseUrl = 'http://localhost:8080/wiki/';
const baseUrl = `${ process.env.MW_SERVER }${ process.env.MW_SCRIPT_PATH }/index.php?title=`;
import { remote } from 'webdriverio';
const browser = await remote( {
capabilities: {
browserName: 'chrome',
'goog:chromeOptions': {
args: [ '--headless', '--no-sandbox' ],
...( process.env.CI && {
binary: '/usr/bin/chromium'
} )
},
...( process.env.CI && {
'wdio:chromedriverOptions': {
binary: '/usr/bin/chromedriver'
}
} ),
'wdio:enforceWebDriverClassic': true
}
} );
await browser.url( `${ baseUrl }Main_Page` );
const displayed = await browser.$( 'li#pt-login-2 a' ).isDisplayed();
if ( displayed === false ) {
throw new Error( 'Log in link not visible' );
} else {
console.log( 'Log in link visible' );
}
await browser.deleteSession();
Output
[edit]Output if everything is fine.
node tests/selenium/docs/Stack/webdriverio.js
...
Log in link visible
...
Output if there is a problem.
node tests/selenium/docs/Stack/webdriverio.js
...
Error: Log in link not visible
...
Mocha
[edit]Stack
[edit]| Language | JavaScript/Node.js |
| Browser | Chrome |
| Selenium/WebDriver | WebdriverIO (web, API, package) |
| Testing framework | Mocha |
| Assertion library | N/A |
| Page object | N/A |
Advantages
[edit]- Testing framework (setup, teardown, reporting...).
Disadvantages
[edit]- No assertions.
- No page object pattern.
Code
[edit]tests/selenium/docs/Stack/specs/mocha.js
// baseUrl is required for our continuous integration.
// If you don't have MW_SERVER and MW_SCRIPT_PATH environment variables set
// you can probably hardcode it to something like this:
// const baseUrl = 'http://localhost:8080/wiki/';
const baseUrl = `${ process.env.MW_SERVER }${ process.env.MW_SCRIPT_PATH }/index.php?title=`;
describe( 'Main page', () => {
it( 'should have "Log in" link when using mocha', async () => {
await browser.url( `${ baseUrl }Main_Page` );
const displayed = await $( 'li#pt-login-2 a' ).isDisplayed();
if ( displayed === false ) {
throw new Error( 'Log in link not visible' );
} else {
console.log( 'Log in link visible' );
}
} );
} );
Output
[edit]Output if everything is fine.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/mocha.js
...
... Main page
... ✓ should have "Log in" link
... 1 passing (1.3s)
Spec Files: 1 passed, 1 total (100% completed) in 00:00:03
Output if there is a problem.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/mocha.js
...
... Main page
... ✖ should have "Log in" link
... 1 failing (1.4s)
...
Spec Files: 0 passed, 1 failed, 1 total (100% completed) in 00:00:04
Expect
[edit]Stack
[edit]| Language | JavaScript/Node.js |
| Browser | Chrome |
| Selenium/WebDriver | WebdriverIO (web, API, package) |
| Testing framework | Mocha |
| Assertion library | Expect |
| Page object | N/A |
Advantages
[edit]- Testing framework (setup, teardown, reporting...).
- Assertions.
Disadvantages
[edit]- No page object pattern.
Code
[edit]tests/selenium/docs/Stack/specs/expect.js
// baseUrl is required for our continuous integration.
// If you don't have MW_SERVER and MW_SCRIPT_PATH environment variables set
// you can probably hardcode it to something like this:
// const baseUrl = 'http://localhost:8080/wiki/';
const baseUrl = `${ process.env.MW_SERVER }${ process.env.MW_SCRIPT_PATH }/index.php?title=`;
describe( 'Main page', () => {
it( 'should have "Log in" link when using expect', async () => {
await browser.url( `${ baseUrl }Main_Page` );
await expect( $( 'li#pt-login-2 a' ) ).toExist();
} );
} );
Output
[edit]Output if everything is fine.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/expect.js
...
... Main page
... ✓ should have "Log in" link when using expect
... 1 passing (1.2s)
Spec Files: 1 passed, 1 total (100% completed) in 00:00:03
Output if there is a problem.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/expect.js
...
... Main page
... ✖ should have "Log in" link when using expect
... 1 failing (5.9s)
...
Spec Files: 0 passed, 1 failed, 1 total (100% completed) in 00:00:03
Page object
[edit]Stack
[edit]| Language | JavaScript/Node.js |
| Browser | Chrome |
| Selenium/WebDriver | WebdriverIO (web, API, package) |
| Testing framework | Mocha |
| Assertion library | Expect |
| Page object | WebdriverIO Page Object Pattern |
Advantages
[edit]- Testing framework (setup, teardown, reporting...).
- Assertions.
- Page object pattern.
Disadvantages
[edit]- Several new tools to learn.
Code
[edit]tests/selenium/docs/Stack/pageobjects/page.js
export default class Page {
open( path ) {
return browser.url( path );
}
}
tests/selenium/docs/Stack/pageobjects/main.page.js
import Page from './page.js';
// baseUrl is required for our continuous integration.
// If you don't have MW_SERVER and MW_SCRIPT_PATH environment variables set
// you can probably hardcode it to something like this:
// const baseUrl = 'http://localhost:8080/wiki/';
const baseUrl = `${ process.env.MW_SERVER }${ process.env.MW_SCRIPT_PATH }/index.php?title=`;
class MainPage extends Page {
get login() {
return $( 'li#pt-login-2 a' );
}
async open() {
await super.open( `${ baseUrl }Main_Page` );
}
}
export default new MainPage();
stests/selenium/docs/Stack/specs/pageobject.js
import MainPage from '../pageobjects/main.page.js';
describe( 'Main Page', () => {
it( 'should have "Log in" link when using page object', async () => {
await MainPage.open();
await expect( MainPage.login ).toExist();
} );
} );
Output
[edit]Output if everything is fine.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/page-object.js
...
... Main Page
... ✓ should have "Log in" link
... 1 passing (1.1s)
Spec Files: 1 passed, 1 total (100% completed) in 00:00:03
Output if there is a problem.
npm run selenium-test -- --spec tests/selenium/docs/Stack/specs/page-object.js
...
... Main Page
... ✖ should have "Log in" link
... 1 failing (1.1s)
...
Spec Files: 0 passed, 1 failed, 1 total (100% completed) in 00:00:03