Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Component Testing with WebdriverIO

Component Testing with WebdriverIO

With more frontend frameworks on the rise web component testing becomes a crucial part of everyones testing stack. It allows to test various features of a single component of your UI and can help to reduce the amount of e2e around it that usually would run slower.

There are already many component testing tools available but almost all of them miss an important feature: running the test in an actual browser. While one might argue that running test in a virtual DOM is fine for testing why not just run them in the browser if you can. With WebdriverIO v8 and its new browser runner capabilities, you can now execute unit or component tests directly in the browser with no complicated set-up required and use the power of the WebDriver protocol to seamlessly interact with them, as a user would do.

In this session, Christian Bromann, Founding Engineer at Stateful, will tell you all about the new browser runner capabilities and will show case hands on live demos testing components in Vue, Svelte, React or Preact. Be amazed as component testing has never been so easy before!

Christian Bromann

March 29, 2023
Tweet

More Decks by Christian Bromann

Other Decks in Technology

Transcript

  1. WebdriverIO
    Component Testing in the Browser

    View full-size slide

  2. Holà 👋
    I am Christian!
    Lead maintainer of the WebdriverIO Project.
    Cross Council Project Member at OpenJS Foundation
    Open Source and Open Standard Advocate
    Working with the awesome folks over at
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  3. Contents
    01 What are Web Components? 🧱
    What are Web Components and why do they matter? How do
    they look like when using React, Svelte, Vue etc.?
    02 Testing Principles 📜
    How can we improve the stability of our tests and
    increase test coverage by shifting to smaller test units?
    03 Status Quo 📏
    What are people already using today and why the heck
    should I care?
    04 WebdriverIO Setup 🛠
    How to get started with WebdriverIO and component /
    unit testing in my project?
    05 Live Coding 󰳕
    Let’s see WebdriverIO component tests in action and check
    out features like mocking to test coverage reporting.
    06 What’s Next? 🚀
    An outlook into the WebdriverIO roadmap in regards to
    web-component testing
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  4. What are
    Web Components?
    🧱
    What are Web Components and why do they matter? How do they look like when using React, Svelte, Vue etc.?

    View full-size slide


  5. <br/>p { color: #00B56C }<br/>

    Hello !


    <br/>class HelloWorld extends HTMLElement {<br/>connectedCallback() {<br/>const shadow = this.attachShadow({ mode: 'closed' })<br/>const template = document.getElementById('hello-world')<br/>shadow.append(template.content.cloneNode(true));<br/>}<br/>}<br/>customElements.define('hello-world', HelloWorld);<br/>
    Hello World!
    Selenium Conf
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  6. <br/>import { LitElement, html, css } from "https://esm.sh/[email protected]";<br/>class HelloWorld extends LitElement {<br/>static get styles() {<br/>return css`p { color: #00B56C }`;<br/>}<br/>render () {<br/>return html`<br/><p><br/>Hello <slot></slot>!<br/></p><br/>`<br/>}<br/>}<br/>customElements.define('hello-world', HelloWorld);<br/>
    Hello World!
    Selenium Conf
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  7. import React from 'react';
    import ReactDOM from 'react-dom/client';
    export function HelloWorld(props) {
    return (

    Hello {props.children}

    );
    }
    export function App(props) {
    return (Selenium Conf)
    }
    ReactDOM.createRoot(
    document.querySelector('#root')
    ).render()
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  8. Testing Principles 📜
    How can we improve the stability of our tests and increase test coverage by shifting to smaller test units?

    View full-size slide

  9. The Testing Pyramid
    Picture from https://www.headspin.io/blog/the-testing-pyramid-simplified-for-one-and-all

    View full-size slide

  10. The Testing Trophy
    Source: https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications
    End to End
    A helper robot that behaves like a user to click
    around the app and verify that it functions correctly.
    Integration
    Verify that several units work
    together in harmony.
    Unit
    Verify that individual, isolated
    parts work as expected.
    Static
    Catch typos and type errors as
    you write the code.
    High Confidence
    Low Confidence
    Slow Execution
    Fast Execution

    View full-size slide

  11. UI Component Dependencies
    UI Component
    Backend Database
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  12. Status Quo 📏
    What are people already using today and why the heck should I care?

    View full-size slide

  13. “Jest is a JavaScript test runner that lets you access the DOM
    via jsdom. While jsdom is only an approximation of how the
    browser works, it is often good enough for testing React
    components.”
    reactjs.org
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  14. @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  15. @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  16. JSDOM
    Caveats
    ● Interactions with components can only be imitated via JavaScript
    ● Missing Web APIs
    ○ Module scripts (ESM)
    ○ Fetch API
    ○ CORS
    ○ …
    ● Canvas support requires additional dependencies and has limitations
    ● May behave different than Web APIs implemented in actual browsers
    ● No element pseudo states, e.g. :hover or :active
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  17. JSDOM
    Caveats
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  18. 🙈🙉
    🙊
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  19. 🙈🙉
    🙊
    .btn {
    visibility: hidden
    }


    Button
    Click Fails
    Button
    Clicked
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  20. 🙈🙉
    🙊
    .btn {
    height: 0px
    }


    Button
    Click Fails
    Button
    Clicked
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  21. 🙈🙉
    🙊
    .forgotEmailOrPassword {
    transform: translateY(-50px)
    }


    Button
    Click Fails
    Button
    Clicked
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  22. 🙈🙉
    🙊
    .forgotEmailOrPassword {
    transform: translateX(10000px)
    }


    Button
    Click Fails
    Button
    Clicked

    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  23. 🙈🙉
    🙊

    Scroll Action

    User Pinch Zoom
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  24. import { render } from '@testing-library/react'
    import { mock, fn } from '@wdio/browser-runner'
    // or
    import { vi } from 'vitest'
    const mock = vi.mock
    const fn = vi.fn
    import { InstantSearchComponent } from './InstantSearch'
    mock('algoliasearch/lite', () => ({
    default: fn().mockReturnValue({
    search: fn().mockImplementation(async () => {
    const fixture = await import('./__fixtures__/algolia.json')
    return Promise.resolve(fixture)
    }),
    searchForFacetValues: fn(),
    addAlgoliaAgent: fn(),
    clearCache: fn()
    })
    }))
    mock('../constants', () => ({
    HEADING: 'mocked out'
    }))
    describe('InstantSearch Component', () => {
    before(() => {
    // render component
    render()
    })
    it('...', async () => {
    // ...
    })
    })
    Mocking

    Dependencies
    Modules
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide


  25. @bromann
    |
    mastodon.social/@bromann
    Hidden Element
    Zero Height
    Overlaying Element
    Out of Viewport
    Support Scroll Action
    Support Pinch Zoom
    Support Mocking













    ❌ ❌
    ❌ ❌
    Overview

    View full-size slide

  26. WebdriverIO Setup 🛠
    How to get started with WebdriverIO and component / unit testing in my project?

    View full-size slide

  27. @bromann
    |
    mastodon.social/@bromann
    Component Testing
    with WebdriverIO

    View full-size slide

  28. Component Testing
    with WebdriverIO
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  29. Component Testing
    with WebdriverIO
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  30. Live Coding 󰳕
    Let’s see WebdriverIO component tests in action and check out features like mocking to test coverage reporting.
    https://github.com/christian-bromann/seconf-2023-demo

    View full-size slide

  31. React Preact Vue
    Pick Your Framework 🤔
    Svelte Lit Solid
    @bromann
    |
    mastodon.social/@bromann

    View full-size slide

  32. What’s Next? 🚀
    An outlook into the WebdriverIO roadmap in regards to web-component testing

    View full-size slide

  33. ● Improved mocking capabilities / fixing known issues
    ● Support for more testrunner, e.g. Jasmine or Cucumber
    ● Snapshot testing support for images and DOM nodes
    const component = render()
    await expect($(component)).toMatchSnapshot()
    ● Improve support for more frameworks, e.g. AngularJS
    ● What else?
    @bromann
    |
    mastodon.social/@bromann
    Component Testing
    with WebdriverIO

    View full-size slide

  34. Thank You!
    @bromann
    mastodon.social/@bromann

    View full-size slide