Selenium/Explanation/Stack

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 in link is present
  • close browser

WebdriverIO

edit

Reasons for selecting WebdriverIO:

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

'use strict';

// 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=`;

const { remote } = require( 'webdriverio' );

( async () => {
  const browser = await remote( {
    capabilities: {
      browserName: 'chrome',
      'goog:chromeOptions': {
        args: [ 'headless' ]
      }
    }
  } );

  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

'use strict';

// 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

'use strict';

// 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( await $( '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

'use strict';

class Page {
        async open( path ) {
                await browser.url( path );
        }
}
module.exports = Page;

tests/selenium/docs/Stack/pageobjects/main.page.js

'use strict';

const Page = require( './page' );

// 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` );
  }
}
module.exports = new MainPage();

stests/selenium/docs/Stack/specs/pageobject.js

'use strict';

const MainPage = require( '../pageobjects/main.page' );

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