Jest + Selenium WebDriverJest + Selenium WebDriver

2018-12-14 16:54:05 浏览数 (1)

代码语言:javascript复制
/**
 * @jest-environment jest-environment-webdriver
 */

const url = 'https://www.actionherojs.com'

describe('www.actionherojs.com#index', () => {
  test('it renders', async () => {
    await browser.get(url)
    const title = await browser.findElement(by.tagName('h2')).getText()
    expect(title).toContain('reusable, scalable, and quick')
  })

  test('loads the latest version number from GitHub', async () => {
    const foundAndLoadedCheck = async () => {
      await until.elementLocated(by.id('latestRelease'))
      const value = await browser.findElement(by.id('latestRelease')).getText()
      return value !== '~'
    }

    await browser.wait(foundAndLoadedCheck, 3000)
    const latestRelease = await browser.findElement(by.id('latestRelease')).getText()
    expect(latestRelease).toEqual('v18.1.3')
  })

  describe('save a screenshot from the browser', () => {
    test('save a picture', async () => {
      // files saved in ./reports/screenshots by default
      await browser.get(url)
      await browser.takeScreenshot()
    })
  })
})

Jest Selenium WebDriver

https://medium.com/@mathieux51/jest-selenium-webdriver-e25604969c6

This week at work, I had to test a React app using Selenium. Because we’re using Jest to test React components/sagas, I thought I would give a shot at making Jest work with Selenium WebDriver. First, let’s npm install what we’ll need:

npm install selenium-webdriver@3.x chromedriver geckodriver jest -D If you’re on mac, you can also test Safari. Just check that you have it available by typing this command in your terminal:

safaridriver Something like this will come out:

代码语言:javascript复制
Usage: safaridriver [options]
 -h, --help                Prints out this usage information.
[...]

If you’re on windows and you want to test IE, you should start downloading the driver here.

Now we can import what we need from these packages:

代码语言:javascript复制
// index.test.js
const { Builder, By, Key, until } = require('selenium-webdriver')
require('selenium-webdriver/chrome')
require('selenium-webdriver/firefox')
require('chromedriver')
require('geckodriver')

Then we need to initialize Selenium:

代码语言:javascript复制
const rootURL = 'https://www.mozilla.org/en-US/'
const d = new Builder().forBrowser('firefox').build()
const waitUntilTime = 20000
let driver, el, actual, expected
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5

Because of how Selenium works, we have to create two utility functions:

代码语言:javascript复制
async function getElementById(id) {
  const el = await driver.wait(until.elementLocated(By.id(id)), waitUntilTime)
  return await driver.wait(until.elementIsVisible(el), waitUntilTime)
}
async function getElementByXPath(xpath) {
  const el = await driver.wait(until.elementLocated(By.xpath(xpath)), waitUntilTime)
  return await driver.wait(until.elementIsVisible(el), waitUntilTime)
}

We can now select an element on the page once it becomes “visible”.

If this element is already supposed to be on the page, we can use:

代码语言:javascript复制
await driver.findElement({ id: 'someId' }).sendKeys('foo')

However, if the element isn’t on the page yet, this command will wait for it to become visible:

代码语言:javascript复制
el = await getElementById('someId')

Most importantly, we need to write two tests that will start and initialise the driver:

代码语言:javascript复制
it('waits for the driver to start', () => {
  return d.then(_d => {
    driver = _d
  })
})

it('initialises the context', async () => {
  await driver.manage().window().setPosition(0, 0)
  await driver.manage().window().setSize(1280, 1024)
  await driver.get(rootURL)
})

Let’s have a look at the page we’re testing:

https://www.mozilla.org/en-US/ Knowing the id, we’re able to target the first item of the navbar. Let’s test if the text of the first element in the drawer contains “Firefox” (Sorry, it’s not a very exciting test ?).

代码语言:javascript复制
it('should click on navbar button to display a drawer', async () => {
  el = await getElementById('nav-button-menu')
  el.click()
  el = await getElementByXPath('//*[@id="moz-global-nav-drawer"]/div/div/ul/li[1]/h3/a')
  
  actual = await el.getText()
  expected = 'Firefox'
  expect(actual).toEqual(expected)
})

After running npm run test we should see something like this in the terminal.

jest.gif

That’s all folks! I hope that helped, and feel free to give me any feedback that can improve my testing workflow.

I created a github repo with all the code needed to make this work: https://github.com/mathieux51/jest-selenium

https://github.com/alexeyraspopov/jest-webdriver

Testing javascript applications with Selenium, Async/Await, and Jest

https://blog.evantahler.com/testing-javascript-applications-with-selenium-async-await-and-jest-7580ed074f2b

First, you’ll need to install a few things into your node.js project:

npm install --save-dev jest jest-environment-webdriver

if you don't have homebrew: https://brew.sh/

brew install chromedriver

chromedriver is a version of the Chrome browser which is able to be “machine controlled” by selenium in our tests. Note that we do not need to install anything else like the selenium server.

Jest already has support for multiple “renderers”. This is how it handles testing compiled-to-javascript files, like JSX. This means that we can signal to Jest in a given test file that it should use selenium. Jest uses magic comments for this:

代码语言:javascript复制
/**
 * @jest-environment jest-environment-webdriver
 */

The default is to use chromedriver, which is what we’ll be using, but you can also test with Firefox, Safari, and other browsers. Using jest-environment-webdriver means that we get a few new global variables we can use in our tests, specifically browser, until, and by(full list here), which we will use in our test.

From here on out, you can use normal Jest commands to start your server in before blocks, configure whatever you need… and control your browser in the test. We can continue to use the normal Jest/Jasmine assertions. In this example, we’ll be testing www.actionherojs.com for a few things, but you’ll probably be testing localhost.

File Location: tests/integration/test.js

Your test can now be run via the normal jest command. That’s it!

代码语言:javascript复制
jest __tests__/integration/simple.js

PASS tests/integration/simple.js www.actionherojs.com#index ✓ it renders (770ms) ✓ loads the latest version number from GitHub (267ms) save a screenshot from the browser ✓ save a picture (784ms) Test Suites: 1 passed, 1 total Tests: 3 passed, 3 total Snapshots: 0 total Time: 3.204s, estimated 6s Note that there is no need to start or stop the chromedriver or selenium server (this handled for you).

Selenium is very powerful (full api docs here). You can type input, scroll the page, get and set cookies, etc. If you do find that you need a “full” integration test, this is a very painless way to do it!

0 人点赞