Jest + Selenium WebDriver

作者: 光剑书架上的书 | 来源:发表于2018-11-22 13:35 被阅读5次
    /**
     * @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:

    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:

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

    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:

    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:

    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:

    el = await getElementById('someId')
    

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

    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 😑).

    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:

    /**
     * @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!

    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!

    相关文章

      网友评论

        本文标题:Jest + Selenium WebDriver

        本文链接:https://www.haomeiwen.com/subject/oaklqqtx.html