<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://webdriver.io/de/blog</id>
    <title>WebdriverIO Blog</title>
    <updated>2026-02-04T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://webdriver.io/de/blog"/>
    <subtitle>WebdriverIO Blog</subtitle>
    <icon>https://webdriver.io/de/img/favicon.png</icon>
    <entry>
        <title type="html"><![CDATA[Introducing WebdriverIO MCP: We're Late, But We Brought Snacks]]></title>
        <id>https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp</id>
        <link href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp"/>
        <updated>2026-02-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Yes, we know. Playwright has an MCP server. Appium has one too. We're not first to the party.]]></summary>
        <content type="html"><![CDATA[<p>Yes, we know. <a href="https://github.com/microsoft/playwright-mcp" target="_blank" rel="noopener noreferrer" class="">Playwright has an MCP server</a>. <a href="https://github.com/anthropics/mcp-server-appium" target="_blank" rel="noopener noreferrer" class="">Appium has one too</a>. We're not first to the party.</p>
<p>But if you're already using WebdriverIO for cross-platform testing, you know it handles both web and mobile in one framework. Why should your AI assistant need two separate MCP servers to do the same thing?</p>
<p>That's why we built <code>@wdio/mcp</code>. One server for browsers and mobile apps, built on the WebdriverIO you already know.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="what-it-does">What It Does<a href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp#what-it-does" class="hash-link" aria-label="Direkter Link zu What It Does" title="Direkter Link zu What It Does" translate="no">​</a></h2>
<p>Hook up Claude (or any MCP-compatible assistant) and start automating:</p>
<ul>
<li class=""><strong>Desktop Browsers</strong> - Chrome, headed or headless</li>
<li class=""><strong>Native Mobile Apps</strong> - iOS Simulators, Android Emulators, real devices via Appium</li>
<li class=""><strong>Hybrid Apps</strong> - Switch between native and webview contexts</li>
</ul>
<p>The nice part: you can say <em>"test the login flow on iPhone 15"</em> then <em>"now try the same on Chrome desktop"</em> without switching tools or reconfiguring. Same conversation, same context.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="quick-start">Quick Start<a href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp#quick-start" class="hash-link" aria-label="Direkter Link zu Quick Start" title="Direkter Link zu Quick Start" translate="no">​</a></h2>
<p>Add this to your Claude Desktop or Claude Code MCP config:</p>
<div class="language-json codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-json codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"mcpServers"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"wdio-mcp"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token property" style="color:#36acaa">"command"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"npx"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token property" style="color:#36acaa">"args"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"-y"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@wdio/mcp"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Restart Claude, and you're ready to go:</p>
<div class="language-text codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-text codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">"Open Chrome and navigate to https://webdriver.io"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Click the Get Started button"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Take a screenshot"</span><br></span></code></pre></div></div>
<p>For mobile:</p>
<div class="language-text codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-text codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">"Launch my app on iPhone 15 simulator"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Tap the login button"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">"Swipe up to scroll"</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="why-not-just-use-playwright-mcp--appium-mcp">Why Not Just Use Playwright MCP + Appium MCP?<a href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp#why-not-just-use-playwright-mcp--appium-mcp" class="hash-link" aria-label="Direkter Link zu Why Not Just Use Playwright MCP + Appium MCP?" title="Direkter Link zu Why Not Just Use Playwright MCP + Appium MCP?" translate="no">​</a></h2>
<p>You could, and they're solid tools. But if your testing already spans web and mobile, managing two MCP servers adds friction - two configs, two mental models, and an assistant that needs to know which tool to reach for.</p>
<p>With <code>@wdio/mcp</code>, the assistant doesn't need to care whether it's talking to a browser or a phone. It sends commands and WebdriverIO handles the rest.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="whats-next-cloud-testing">What's Next: Cloud Testing<a href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp#whats-next-cloud-testing" class="hash-link" aria-label="Direkter Link zu What's Next: Cloud Testing" title="Direkter Link zu What's Next: Cloud Testing" translate="no">​</a></h2>
<p>Local automation is useful for development and exploration, but real validation needs scale. We're working on cloud provider support, starting with BrowserStack.</p>
<p>The goal: point your AI assistant at a device farm and validate your app across dozens of browser and device combinations. Describe what you want to verify, and let the assistant handle execution across the matrix.</p>
<p>BrowserStack integration is first, with LambdaTest and Sauce Labs on the roadmap.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="learn-more">Learn More<a href="https://webdriver.io/de/blog/2026/02/04/introducing-webdriverio-mcp#learn-more" class="hash-link" aria-label="Direkter Link zu Learn More" title="Direkter Link zu Learn More" translate="no">​</a></h2>
<p>Full documentation at <a class="" href="https://webdriver.io/de/docs/mcp">MCP docs</a> - setup guides, tool reference, and selector syntax for web and mobile.</p>
<p>Questions or feedback? Find us on <a href="https://discord.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">Discord</a>.</p>
<p>Happy testing!</p>]]></content>
        <author>
            <name>Vince Graics</name>
            <uri>https://github.com/Winify</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[WebdriverIO v9 Released]]></title>
        <id>https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release</id>
        <link href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release"/>
        <updated>2024-08-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The whole Webdriverio development team is stoked and proud to release WebdriverIO v9 today!]]></summary>
        <content type="html"><![CDATA[<p>The whole Webdriverio development team is stoked and proud to release WebdriverIO v9 today!</p>
<p>This marks the beginning of a new exciting era for all projects using WebdriverIO as their test automation tool. With the great work of browser teams that are working on e.g. Chrome and Firefox, we now enter a new era that offers much greater automation capabilities than ever before thanks to the new <a href="https://w3c.github.io/webdriver-bidi/" target="_blank" rel="noopener noreferrer" class="">WebDriver Bidi</a> protocol. With WebdriverIO v9 we have been working to be at the forefront of adopters of this new era and allow you to leverage from the power of the protocol first.</p>
<p>Let's explore the new features, updates, and optimizations in this release.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="new-features">New Features<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#new-features" class="hash-link" aria-label="Direkter Link zu New Features" title="Direkter Link zu New Features" translate="no">​</a></h2>
<p>The majority of the new features in v9 are enabled by the WebDriver Bidi capabilities now available in browsers. Upon upgrading to v9, all sessions will automatically use Bidi unless you explicitly disable it via the new <code>wdio:enforceWebDriverClassic</code> capability.</p>
<div class="theme-admonition theme-admonition-note admonition_lzqF alert alert--secondary"><div class="admonitionHeading_ZWfq"><span class="admonitionIcon_BFei"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Hinweis</div><div class="admonitionContent_dPCE"><p>These features unfortunately won't be available to you if your remote environment doesn't support WebDriver Bidi. You can check if Bidi is support in your session by looking into the <code>browser.isBidi</code> property.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="new-url-command-parameters">New <code>url</code> Command Parameters<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#new-url-command-parameters" class="hash-link" aria-label="Direkter Link zu new-url-command-parameters" title="Direkter Link zu new-url-command-parameters" translate="no">​</a></h3>
<p>The <code>url</code> command has evolved from a simple navigation tool to a powerful feature-packed command.</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="passing-in-custom-headers">Passing in Custom Headers<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#passing-in-custom-headers" class="hash-link" aria-label="Direkter Link zu Passing in Custom Headers" title="Direkter Link zu Passing in Custom Headers" translate="no">​</a></h4>
<p>You can now pass custom headers that will be applied when the browser makes a request. This is useful for setting session cookies to log in automatically.</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://webdriver.io'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    headers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        Authorization</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Bearer XXXXX'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Note that while you can modify how the browser treats all requests through the <a class="" href="https://webdriver.io/de/docs/api/browser/mock"><code>mock</code></a> command, changes applied to the <a class="" href="https://webdriver.io/de/docs/api/browser/url"><code>url</code></a> command only last for that particular page load and reset once navigation is complete.</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="overcome-basic-authentification">Overcome Basic Authentification<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#overcome-basic-authentification" class="hash-link" aria-label="Direkter Link zu Overcome Basic Authentification" title="Direkter Link zu Overcome Basic Authentification" translate="no">​</a></h4>
<p>Automating user authentication via <a href="https://en.wikipedia.org/wiki/Basic_access_authentication" target="_blank" rel="noopener noreferrer" class="">basic authentication</a> has never been easier:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://the-internet.herokuapp.com/basic_auth'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    auth</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        user</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        pass</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'admin'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'p=Congratulations! You must have the proper credentials.'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toBeDisplayed</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="running-an-initialization-script">Running an Initialization Script<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#running-an-initialization-script" class="hash-link" aria-label="Direkter Link zu Running an Initialization Script" title="Direkter Link zu Running an Initialization Script" translate="no">​</a></h4>
<p>Inject JavaScript before anything loads on the website using the <code>beforeLoad</code> parameter. This is useful for manipulating Web APIs, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// navigate to a URL and mock the battery API</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://pazguille.github.io/demo-battery-api/'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">onBeforeLoad</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// mock "navigator.battery" property</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// returning mock charge object</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">navigator</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function-variable function" style="color:#d73a49">getBattery</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            level</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            charging</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            chargingTime</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">Infinity</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            dischargingTime</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// seconds</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// now we can assert actual text - we are charged at 50%</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'.battery-percentage'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'50%'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// and has enough juice for 1 hour</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'.battery-remaining'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">'</span><span class="token number" style="color:#36acaa">01</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">00</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>In this example, we overwrite the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getBattery" target="_blank" rel="noopener noreferrer" class=""><code>getBattery</code></a> method of the <code>Navigator</code> interface.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="new-addinitscript-command">New <code>addInitScript</code> Command<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#new-addinitscript-command" class="hash-link" aria-label="Direkter Link zu new-addinitscript-command" title="Direkter Link zu new-addinitscript-command" translate="no">​</a></h3>
<p>The <code>addInitScript</code> command enables you to inject a script into the browser that is triggered every time a new browsing context is opened. This includes actions such as navigating to a URL or loading an iframe within an application. The script you pass to this command receives a callback as its last parameter, allowing you to send values from the browser back to your Node.js environment.</p>
<p>For instance, to get notified whenever an element is added or removed from a node in the application, you can use the following example:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> script </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">addInitScript</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">myParam</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> emit</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> observer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">MutationObserver</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mutations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mutation </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> mutations</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token function" style="color:#d73a49">emit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mutation</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">nodeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    observer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">observe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">document</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> childList</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> subtree</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">script</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'data'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// prints: BODY, DIV, P, ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>This initialization script can modify global variables and overwrite built-in Web API primitives, allowing you to configure the test environment to meet your specific requirements.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="cross-browser-request-mocking">Cross Browser Request Mocking<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#cross-browser-request-mocking" class="hash-link" aria-label="Direkter Link zu Cross Browser Request Mocking" title="Direkter Link zu Cross Browser Request Mocking" translate="no">​</a></h3>
<p>WebdriverIO introduced request mocking in <a href="https://github.com/webdriverio/webdriverio/blob/v6/CHANGELOG.md#rocket-new-feature-14" target="_blank" rel="noopener noreferrer" class=""><code>v6.3.0</code></a>, limited to Chromium browsers. With v9, we now use WebDriver Bidi, extending support to all browsers. This enhancement allows modifying requests before they go out to the network:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// mock all API requests</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mock </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">mock</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'**/api/**'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// apply auth token to each request</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mock</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">request</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    headers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token string-property property" style="color:#36acaa">'Authorization'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Bearer XXXXXX'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="automatic-shadow-root-piercing">Automatic Shadow Root Piercing<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#automatic-shadow-root-piercing" class="hash-link" aria-label="Direkter Link zu Automatic Shadow Root Piercing" title="Direkter Link zu Automatic Shadow Root Piercing" translate="no">​</a></h3>
<p>Testing applications with Web Components is now seamless with automatic shadow root piercing. WebdriverIO now keeps track of all <a href="https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot" target="_blank" rel="noopener noreferrer" class=""><code>ShadowRoot</code></a> nodes and searches across them.</p>
<p>For example, let's say we want to automate the following Date Picker component that contains multiple nested shadow roots, take a look with <code>Right Click &gt; Inspect</code> on any of the elements in the application and observe how much they are nested within different shadow roots:</p>
<div style="display:block;border:4px solid #444;border-radius:50px;background-color:#000;padding:10px;margin:0 auto 20px;overflow:hidden;width:320px"><div style="position:relative;top:0;left:0;background:#000;height:25px;width:150px;margin:0 auto;border-bottom-left-radius:17px;border-bottom-right-radius:17px;z-index:11"></div><div style="overflow:hidden;border-radius:40px;margin-top:-25px;background-color:#fff"><div style="width:320px;height:568px;display:block;flex-direction:column;align-items:center;justify-content:center"><iframe title="Date Picker" height="580" style="padding-top:40px" width="292px" src="https://ionicframework.com/docs/usage/v8/datetime/basic/demo.html?ionic:mode=md"></iframe></div></div></div>
<p>In order to change the date, you can now just call:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://ionicframework.com/docs/usage/v8/datetime/basic/demo.html?ionic:mode=md'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/Sunday, August 4]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'.aux-input'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getValue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// outputs "2024-08-04T09:00:00"</span><br></span></code></pre></div></div>
<p>While WebdriverIO previously supported <a class="" href="https://webdriver.io/de/docs/selectors#deep-selectors">"deep selectors"</a>, this functionality was limited to CSS selectors. The new selector engine now supports all selector types, including accessibility labels.</p>
<p>With the enhanced locator engine, elements within multiple nested shadow roots can be easily found. WebdriverIO is the first framework to support this capability for shadow roots in both <code>open</code> and <code>closed</code> mode.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="improved-argument-serialization">Improved Argument Serialization<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#improved-argument-serialization" class="hash-link" aria-label="Direkter Link zu Improved Argument Serialization" title="Direkter Link zu Improved Argument Serialization" translate="no">​</a></h3>
<p>With WebDriver Classic the ability to move data objects from the Test to the browser environment was rather limited to DOM elements and serializable objects and types. With WebDriver Bidi we are now able to do a better job transforming non-serializable data objects to be used in the browser as the object that it is. Alongside known JavaScript primitives such as <code>Map</code> or <code>Set</code>, the protocol allows to serialize values such as <code>Infinity</code>, <code>null</code>, <code>undefined</code> and <code>BigInt</code>.</p>
<p>Here is an example where we compose a JavaScript Map object in Node.js and pass it over to the browser where it gets automatically deserialzed back into a Map and vise versa:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> data </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'username'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Tony'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'password'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'secret'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> output </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">data</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation">size</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c"> entrie(s), username: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">data</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation function" style="color:#d73a49">get</span><span class="token template-string interpolation punctuation" style="color:#393A34">(</span><span class="token template-string interpolation string" style="color:#e3116c">'username'</span><span class="token template-string interpolation punctuation" style="color:#393A34">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">, password: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">data</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation function" style="color:#d73a49">get</span><span class="token template-string interpolation punctuation" style="color:#393A34">(</span><span class="token template-string interpolation string" style="color:#e3116c">'secret'</span><span class="token template-string interpolation punctuation" style="color:#393A34">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    data</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">output</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// outputs: "1 entrie(s), username: Tony, password: secret"</span><br></span></code></pre></div></div>
<p>This will make it easier pass data along and work with custom scripts that can now return rich data objects that will help better observe the state of your application. It will allow frameworks like WebdriverIO to integrate deeper with the browser environment and build more useful features in the future.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="setting-viewports">Setting Viewports<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#setting-viewports" class="hash-link" aria-label="Direkter Link zu Setting Viewports" title="Direkter Link zu Setting Viewports" translate="no">​</a></h3>
<p>While WebdriverIO allows you to test your application in both desktop and mobile browsers, it is often easier to emulate a mobile user by adjusting the browser viewport to check if the application renders properly in responsive mode. With WebDriver Classic, this can be challenging because browser windows cannot scale down to very small sizes and often maintain a minimum width of <code>500px</code>. For example:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://webdriver.io'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">setWindowSize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">393</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">659</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> window</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">innerWidth</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns `500`</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="WebdriverIO setWindowSize Result" src="https://webdriver.io/de/assets/images/setWindowSize-a6770c6ce7d1cc9c79de85af25b2bbad.png" width="1224" height="1542" class="img_ahPx"></p>
<p>WebdriverIO v9 introduces the <code>setViewport</code> command, enabling you to adjust the application’s viewport to any size, including modifying the <code>devicePixelRatio</code>. Unlike <code>setWindowSize</code>, which changes the overall browser window size, <code>setViewport</code> specifically resizes the canvas where the application is rendered, leaving the browser window dimensions unchanged.</p>
<p>To simplify mobile device emulation, we’ve enhanced the emulate command. This new capability allows you to simultaneously adjust the viewport size, device pixel ratio, and user agent for a specific mobile device by simply specifying its name. For example:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://webdriver.io'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">emulate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'device'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'iPhone 15'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> window</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">innerWidth</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns `393`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> navigator</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">userAgent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36`</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="WebdriverIO setViewportSize Result" src="https://webdriver.io/de/assets/images/setViewportSize-8f70543f30fae66fb14f81abd1228991.png" width="2624" height="2024" class="img_ahPx"></p>
<p>While we recommend to run mobile testing on actual mobile devices, as mobile browser engines differ from the ones used for desktop browser, this can be an easy escape hatch if we just quickly want to verify how the application renders in mobile viewports.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="fake-timers-support">Fake Timers Support<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#fake-timers-support" class="hash-link" aria-label="Direkter Link zu Fake Timers Support" title="Direkter Link zu Fake Timers Support" translate="no">​</a></h3>
<p>Want to change the time in the browser? With WebdriverIO v9, it's now possible to fake the time within the browser for your tests. We've enhanced the <a class="" href="https://webdriver.io/de/docs/emulation"><code>emulate</code></a> command with a new property: <code>clock</code>. This allows you to set the date and time to whatever you need and control when time should advance. Here's how it works:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> clock </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">emulate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'clock'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> now</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2021</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">14</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getTime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns 1618383600000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> clock</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">tick</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Date</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getTime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns 1618383601000</span><br></span></code></pre></div></div>
<p>The new <code>clock</code> emulation returns a <a class="" href="https://webdriver.io/de/docs/api/clock"><code>Clock</code></a> object with methods like <code>tick</code>, <code>setSystemTime</code>, and <code>restore</code> for precise control over the time in your tests.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="automatic-dialog-handling">Automatic Dialog Handling<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#automatic-dialog-handling" class="hash-link" aria-label="Direkter Link zu Automatic Dialog Handling" title="Direkter Link zu Automatic Dialog Handling" translate="no">​</a></h3>
<p>If your application works with native browser dialogs, e.g. <code>alert</code> or <code>confirm</code>, it sometime can be tricky when these prompts show up unexpectedly. In previous versions all commands would fail if you don't handle them properly. With WebdriverIO v9 we will start automatically suppressing dialogs, unless you explicitly register a listener to it, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://webdriver.io'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'dialog'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">dialog</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">dialog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">message</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// outputs: "Hello Dialog"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> dialog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">dismiss</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">alert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Hello Dialog'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>The new <code>dialog</code> event gets a <a class="" href="https://webdriver.io/de/docs/api/dialog">dialog</a> object passed in that allows you to call <code>accept</code> or <code>dismiss</code> on it, get the type or message of the dialog as well as its default value. We hope this will break less tests in the future due to unexpected alerts by the browser.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="automatic-waiting-for-elements-to-become-interactable">Automatic waiting for elements to become interactable<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#automatic-waiting-for-elements-to-become-interactable" class="hash-link" aria-label="Direkter Link zu Automatic waiting for elements to become interactable" title="Direkter Link zu Automatic waiting for elements to become interactable" translate="no">​</a></h3>
<p>An element is considered not to be interactable when it is either not displayed, cannot be scrolled into the viewport or is disabled and previously WebdriverIO would would throw an error when this would happen. In v8 we already made an improvement of showing the html of the element but in v9 we now automatically wait for elements to become interactable when executing a direct action on the element, like a click or using setValue!</p>
<p>This means that you no longer need to write code like this:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> submitButton </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'button[type="submit"]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> submitButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">waitForEnabled</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// validation of the form takes time, during which the button is disabled</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> submitButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>Instead you can now slim this down to:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> submitButton </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'button[type="submit"]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> submitButton</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// automatically waits for the button to become enabled</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="snapshot-testing-of-web-components">Snapshot Testing of Web Components<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#snapshot-testing-of-web-components" class="hash-link" aria-label="Direkter Link zu Snapshot Testing of Web Components" title="Direkter Link zu Snapshot Testing of Web Components" translate="no">​</a></h3>
<p>If your application uses a lot of web components, using the snapshot feature turned out to be not possible due to the fact that WebdriverIO struggled to look inside the <a href="https://www.google.com/search?q=shadow+root+mdn&amp;sourceid=chrome&amp;ie=UTF-8" target="_blank" rel="noopener noreferrer" class="">Shadow Root</a>. With v9 WebdriverIO has now total visibility into all elements an allows to snapshot open and closed web components by transforming them into a <a href="https://web.dev/articles/declarative-shadow-dom" target="_blank" rel="noopener noreferrer" class="">Declarative Shadow DOM</a>, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'https://ionicframework.com/docs/usage/v8/button/basic/demo.html?ionic:mode=md'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// get snapshot of web component without its styles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> snapshot </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'ion-button'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getHTML</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> excludeElements</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'style'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// assert snapshot</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">snapshot</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchInlineSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">    &lt;ion-button class="md button button-solid ion-activatable ion-focusable hydrated"&gt;Default</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">        &lt;template shadowrootmode="open"&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;button type="button" class="button-native" part="native"&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;span class="button-inner"&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">                &lt;slot name="icon-only"&gt;&lt;/slot&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">                &lt;slot name="start"&gt;&lt;/slot&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">                &lt;slot&gt;&lt;/slot&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">                &lt;slot name="end"&gt;&lt;/slot&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;/span&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;ion-ripple-effect role="presentation" class="md hydrated"&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">                &lt;template shadowrootmode="open"&gt;&lt;/template&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;/ion-ripple-effect&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">            &lt;/button&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">        &lt;/template&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c">    &lt;/ion-button&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"></span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>To enable this feature we enhanced the <code>getHTML</code> command and replaced its previous boolean parameter with an object that allows better control about the command behavior. Read more about the new <code>GetHTMLOptions</code> options in the <a class="" href="https://webdriver.io/de/docs/api/element/getHTML"><code>getHTML</code></a> command docs.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="notable-breaking-changes">Notable Breaking Changes<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#notable-breaking-changes" class="hash-link" aria-label="Direkter Link zu Notable Breaking Changes" title="Direkter Link zu Notable Breaking Changes" translate="no">​</a></h2>
<p>We strive to minimize breaking changes to avoid requiring significant time for upgrades to the latest version of WebdriverIO. However, major releases offer an opportunity to remove deprecated interfaces that we no longer recommend using.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="accessing-element-properties">Accessing Element Properties<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#accessing-element-properties" class="hash-link" aria-label="Direkter Link zu Accessing Element Properties" title="Direkter Link zu Accessing Element Properties" translate="no">​</a></h3>
<p>As you know, WebdriverIO allows you to fetch elements from the browser to interact with them in your tests. When you interact with an element, WebdriverIO holds a reference and additional metadata on the element to properly direct commands to the correct element and, for example, refetch an element if it becomes stale. You may have accessed some of these element properties, such as evaluating the selector via <code>$('elem').selector</code> or getting its reference via <code>$('elem').elementId</code>, among <a class="" href="https://webdriver.io/de/docs/api/element#properties">others</a>.</p>
<p>These properties are no longer accessible in this manner. Instead, you need to call <a class="" href="https://webdriver.io/de/docs/api/element/getElement"><code>getElement</code></a> to access properties of <code>WebdriverIO.Element</code> and <a class="" href="https://webdriver.io/de/docs/api/element/getElements"><code>getElements</code></a> to access properties for a <code>WebdriverIO.ElementArray</code>. Here is an example:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// WebdriverIO v8 and older</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> elem </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'elem'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elem</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">selector</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// ❌ returns a `Promise&lt;string&gt;` now</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// WebdriverIO v9</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> elem </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'elem'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getElement</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elem</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">selector</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// ✅ returns "elem"</span><br></span></code></pre></div></div>
<p>This change fixes a <a href="https://github.com/webdriverio/webdriverio/issues/12591" target="_blank" rel="noopener noreferrer" class="">very annoying bug</a> in IDEs that were misled into believing that <code>$('elem')</code> returns a promise, causing them to automatically wrap chained element calls in multiple <code>await</code> statements, e.g., <code>await (await $('elem')).getText()</code>. This improvement will make writing tests much easier.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="removal-of-xxxcontaining-matcher">Removal of <code>XXXContaining</code> Matcher<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#removal-of-xxxcontaining-matcher" class="hash-link" aria-label="Direkter Link zu removal-of-xxxcontaining-matcher" title="Direkter Link zu removal-of-xxxcontaining-matcher" translate="no">​</a></h3>
<p>In <code>expect-webdriverio</code>, we maintain custom matchers tailored for WebdriverIO elements and end-to-end testing scenarios. Previously, we provided <code>XXXContaining</code> versions of each matcher to allow partial value matching. However, the underlying <a href="https://www.npmjs.com/package/expect" target="_blank" rel="noopener noreferrer" class=""><code>expect</code></a> package already supports this functionality via <a href="https://jestjs.io/docs/expect#asymmetric-matchers" target="_blank" rel="noopener noreferrer" class="">asymmetric matchers</a>. To reduce the number of matchers we maintain, we have decided to remove our custom <code>XXXContaining</code> matchers in favor of using these asymmetric matchers.</p>
<p>Migrating to asymmetric matchers is straightforward. Here is an example:</p>
<div class="language-diff codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-diff codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">- await expect($('elem')).toHaveTextContaining('Hello')</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">+ await expect($('elem')).toHaveText(expect.stringContaining('Hello'))</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="removal-of-isdisplayedviewport">Removal of <code>isDisplayedViewport</code><a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#removal-of-isdisplayedviewport" class="hash-link" aria-label="Direkter Link zu removal-of-isdisplayedviewport" title="Direkter Link zu removal-of-isdisplayedviewport" translate="no">​</a></h3>
<p>We have removed the <code>isDisplayedViewport</code> command and merged the functionality with the <code>isDisplayed</code> command, e.g.:</p>
<div class="language-patch codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-patch codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">- await $('element').isDisplayedViewport()</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">+ await $('element').isDisplayed({ withinViewport: true })</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="removal-of-json-wire-protocol-commands">Removal of JSON Wire Protocol Commands<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#removal-of-json-wire-protocol-commands" class="hash-link" aria-label="Direkter Link zu Removal of JSON Wire Protocol Commands" title="Direkter Link zu Removal of JSON Wire Protocol Commands" translate="no">​</a></h3>
<p>The JSON Wire Protocol was the first automation protocol developed by Selenium, enabling remote browser automation using any language that supports HTTP. In 2012, the creators of Selenium began working on formally standardizing the protocol, which is now supported in all browsers. This effort culminated in the WebDriver protocol becoming a W3C Recommendation, leading browser drivers and cloud vendors to migrate to this official standard.</p>
<p>We believe it is time to say farewell to the old JSON Wire Protocol and embrace the WebDriver future. If you are still testing on older browsers and require these protocol commands for your automation scripts, you can install the <a href="https://www.npmjs.com/package/@wdio/jsonwp-service" target="_blank" rel="noopener noreferrer" class=""><code>@wdio/jsonwp-service</code></a> to continue using the necessary commands.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="removal-of-devtools-and-wdiodevtools-service-packages">Removal of <code>devtools</code> and <code>@wdio/devtools-service</code> Packages<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#removal-of-devtools-and-wdiodevtools-service-packages" class="hash-link" aria-label="Direkter Link zu removal-of-devtools-and-wdiodevtools-service-packages" title="Direkter Link zu removal-of-devtools-and-wdiodevtools-service-packages" translate="no">​</a></h3>
<p>With WebdriverIO <code>v8.15</code>, we <a href="https://webdriver.io/blog/2023/07/31/driver-management" target="_blank" rel="noopener noreferrer" class="">introduced</a> an automatic setup for browser drivers as a core feature. This change rendered the original purpose of the <a href="https://www.npmjs.com/package/devtools" target="_blank" rel="noopener noreferrer" class=""><code>devtools</code></a> package obsolete. Initially, the devtools package was designed to implement the WebDriver specification through Puppeteer which handles the browser setup for you. This allowed using WebdriverIO without having to download any browser driver. As this functionality is no longer needed, we have decided to remove the <code>devtools</code> package along with the <code>automationProtocol</code> option.</p>
<p>Furthermore, with the adoption of WebDriver Bidi, we now have a standardized protocol for most of our automation needs. Despite this, using <a href="https://developer.chrome.com/docs/devtools" target="_blank" rel="noopener noreferrer" class="">Chrome Devtools</a> for more complex browser introspection has been a popular feature in WebdriverIO. Previously, we recommended the <code>@wdio/devtools-service</code> package for these use cases. However, we found that most users prefer to use <a href="https://pptr.dev/" target="_blank" rel="noopener noreferrer" class="">Puppeteer</a> directly rather than our custom DevTools interfaces. WebdriverIO users can automate the browser using WebdriverIO primitives as well as Puppeteer simultaneously. By calling the <code>getPuppeteer</code> command, you can obtain a Puppeteer instance for the browser you are automating, granting you access to all Devtools capabilities through a more robust and maintained interface. As a result, users primarily utilize the <code>@wdio/devtools-service</code> package for testing performance and other <a href="https://developer.chrome.com/docs/lighthouse/overview" target="_blank" rel="noopener noreferrer" class="">Google Lighthouse</a> features. Moving on, these features will be available under a new service package called <a href="https://www.npmjs.com/package/@wdio/lighthouse-service" target="_blank" rel="noopener noreferrer" class="">`@wdio/lighthouse-service</a>.</p>
<p>Rest assured, we have already found a good use case for these packages and will not abandon them.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="project-updates">Project Updates<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#project-updates" class="hash-link" aria-label="Direkter Link zu Project Updates" title="Direkter Link zu Project Updates" translate="no">​</a></h2>
<p>While we have been diligently adding new features to make WebdriverIO more effective for testing web and mobile applications, we have also been focusing on several internal initiatives to ensure a bright future for the project.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="pnpm-migration">pnpm Migration<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#pnpm-migration" class="hash-link" aria-label="Direkter Link zu pnpm Migration" title="Direkter Link zu pnpm Migration" translate="no">​</a></h3>
<p>As our core packages have grown over time, we've faced increasing challenges with NPM, particularly with dependency resolution in our monorepo. Additionally, custom linking made our testing infrastructure more complex than necessary.</p>
<p>Given the evolving JavaScript tooling ecosystem, we evaluated and adopted new technologies to improve the developer experience within the project. By migrating to pnpm, we eliminated many custom scripts, simplified the overall project setup, and now enjoy faster, more reliable dependency resolution with fewer merge conflicts in our regular updates via Dependabot.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="esbuild-migration">Esbuild Migration<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#esbuild-migration" class="hash-link" aria-label="Direkter Link zu Esbuild Migration" title="Direkter Link zu Esbuild Migration" translate="no">​</a></h3>
<p>Since introducing TypeScript in <a href="https://github.com/webdriverio/webdriverio/blob/v7/CHANGELOG.md#boom-breaking-change-1" target="_blank" rel="noopener noreferrer" class=""><code>v7</code></a>, we've used the TypeScript compiler to convert files into JavaScript for publishing to NPM. However, as our codebase grew, we encountered challenges with this setup. For example, some files within the <code>webdriverio</code> or <code>@wdio/browser-runner</code> packages are exclusively used in browser environments, yet they were compiled as if for Node.js, causing compatibility issues.</p>
<p>With WebdriverIO v9, all project files are compiled with Esbuild. This versatile and ultra-fast bundler allows us to compile code specifically for the intended environment, ensuring the right polyfills are applied. Additionally, every package is now bundled into a single JavaScript file, slightly improving performance, especially for component testing.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="migration-from-ts-node-to-tsx">Migration from <code>ts-node</code> to <code>tsx</code><a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#migration-from-ts-node-to-tsx" class="hash-link" aria-label="Direkter Link zu migration-from-ts-node-to-tsx" title="Direkter Link zu migration-from-ts-node-to-tsx" translate="no">​</a></h3>
<p>WebdriverIO has transitioned from <code>ts-node</code> to <code>tsx</code> for compiling TypeScript tests into JavaScript at runtime. This change offers better ESM support, improved performance, and more accurate stack traces for errors in TypeScript tests.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="dropping-nodejs-v16-support">Dropping Node.js v16 Support<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#dropping-nodejs-v16-support" class="hash-link" aria-label="Direkter Link zu Dropping Node.js v16 Support" title="Direkter Link zu Dropping Node.js v16 Support" translate="no">​</a></h3>
<p>As with every release, we are discontinuing support for older, unmaintained Node.js versions. WebdriverIO v9 will no longer support Node.js v16 and below. We recommend users upgrade to Node.js v20.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="whats-next">What's Next?<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#whats-next" class="hash-link" aria-label="Direkter Link zu What's Next?" title="Direkter Link zu What's Next?" translate="no">​</a></h2>
<p>As WebdriverIO celebrates its 13th year of development, the need for new testing capabilities continues to grow alongside the evolving testing industry and web standards. With the adoption of the WebDriver Bidi protocol in modern browsers, tools like Selenium, Nightwatch, and WebdriverIO can match the power of Playwright and Cypress without relying on proprietary browser patches or specific execution environments.</p>
<p>WebdriverIO will continue to integrate more WebDriver Bidi features to build powerful new functionalities. We are excited about future developments, including a WebdriverIO devtools application that will significantly enhance the testing experience by providing a powerful UI for inspecting and debugging the application under test. More details on this initiative will be shared soon!</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="acknowledgments">Acknowledgments<a href="https://webdriver.io/de/blog/2024/08/15/webdriverio-v9-release#acknowledgments" class="hash-link" aria-label="Direkter Link zu Acknowledgments" title="Direkter Link zu Acknowledgments" translate="no">​</a></h3>
<p>We extend our gratitude to our Premium Sponsors, <a href="https://www.browserstack.com/" target="_blank" rel="noopener noreferrer" class="">BrowserStack</a> and <a href="https://saucelabs.com/" target="_blank" rel="noopener noreferrer" class="">Sauce Labs</a>, and to everyone who contributes to the project. WebdriverIO remains community-driven and independent, relying on contributions from people like you. Join our <a href="https://webdriver.io/community/openofficehours" target="_blank" rel="noopener noreferrer" class="">Open Office Hours</a> and consider giving back to the project.</p>
<p>Here's to many more years of innovation and collaboration! 🚀</p>
<p>Thank you for reading!</p>]]></content>
        <author>
            <name>WebdriverIO Team</name>
            <uri>https://x.com/webdriverio</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Interacting with Chrome DevTools from WebDriverIO]]></title>
        <id>https://webdriver.io/de/blog/2024/08/12/manipulate-devtools</id>
        <link href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools"/>
        <updated>2024-08-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[WebdriverIO is build to test various types of applications, from web or mobile applications towards native desktop apps or even VS Code extensions. But what about Chrome DevTools plugins? In this blog post we explore how one could interact with an extension build for Chrome Devtools.]]></summary>
        <content type="html"><![CDATA[<p>WebdriverIO is build to test various types of applications, from web or mobile applications towards native desktop apps or even VS Code extensions. But what about Chrome DevTools plugins? In this blog post we explore how one could interact with an extension build for Chrome Devtools.</p>
<p>WebdriverIO is build to test various types of applications, from web or mobile applications towards native desktop apps or even VS Code extensions. But what about Chrome DevTools plugins? In this blog post we explore how one could interact with an extension build for Chrome Devtools.</p>
<p>One of WebDriverIO features is the ability to interact with Chrome DevTools, which can be extremely helpful for debugging and testing web applications and browser extensions. In this blog, we'll explore how to use WebDriverIO to interact with the Chrome DevTools, specifically focusing on interacting with the PixiJS extension.
You can find a complete example in <a href="https://github.com/gromanas/wdio-devtools-demo" target="_blank" rel="noopener noreferrer" class="">Github</a>.</p>
<h1>Devtools in WebdriverIO</h1>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="setting-up-extension">Setting Up Extension<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#setting-up-extension" class="hash-link" aria-label="Direkter Link zu Setting Up Extension" title="Direkter Link zu Setting Up Extension" translate="no">​</a></h2>
<p>You need to download the extension you want to test in a <code>.crx</code> format,
in our case we have downloaded the <code>PixiJS-Devtools-Chrome-Web-Store.crx</code> extension file.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="setting-up-webdriverio">Setting Up WebDriverIO<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#setting-up-webdriverio" class="hash-link" aria-label="Direkter Link zu Setting Up WebDriverIO" title="Direkter Link zu Setting Up WebDriverIO" translate="no">​</a></h2>
<p>First, ensure you have WebDriverIO set up in your project. If not, you can install it by following the official installation guide <a href="https://webdriver.io/docs/gettingstarted#initiate-a-webdriverio-setup" target="_blank" rel="noopener noreferrer" class="">here</a></p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="webdriverio-configuration-for-chrome-devtools">WebDriverIO Configuration for Chrome DevTools<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#webdriverio-configuration-for-chrome-devtools" class="hash-link" aria-label="Direkter Link zu WebDriverIO Configuration for Chrome DevTools" title="Direkter Link zu WebDriverIO Configuration for Chrome DevTools" translate="no">​</a></h2>
<p>Here is the configuration file (<code>wdio.conf.js</code>) tailored to our example:</p>
<div class="language-javascript codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-javascript codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">path</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"path"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">fs</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"fs"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> config </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">specs</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"./test/specs/**/*.js"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">runner</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"local"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">maxInstances</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">capabilities</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">browserName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"chrome"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">browserVersion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"stable"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">"goog:chromeOptions"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">args</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">"ignore-certificate-errors-spki-list"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">"--ignore-certificate-errors"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">"window-size=1920,1080"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token string" style="color:#e3116c">"--auto-open-devtools-for-tabs"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">extensions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          fs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">readFileSync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"./PixiJS-Devtools-Chrome-Web-Store.crx"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"base64"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">logLevel</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"debug"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">framework</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"mocha"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">mochaOpts</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">ui</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"bdd"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">timeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 5 min</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<p>In this configuration, we specify the Chrome browser with options to auto-open DevTools for tabs and load the PixiJS DevTools extension. The <code>extensions</code> option reads the extension file in base64 format.
We need also the <code>--auto-open-devtools-for-tabs</code> flag to automatically open the DevTools (Developer Tools) panel.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="writing-the-test-script">Writing the Test Script<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#writing-the-test-script" class="hash-link" aria-label="Direkter Link zu Writing the Test Script" title="Direkter Link zu Writing the Test Script" translate="no">​</a></h2>
<p>Next, we write a test script to interact with the PixiJS extension through Chrome DevTools. Create a test file, for example, <code>devtools.test.js</code>, and add the following code:</p>
<div class="theme-tabs-container tabs-container tabList_nQye"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_RBde tabs__item--active">WebDriver primitives</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_RBde">Puppeteer</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Y7ux"><div class="language-javascript codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-javascript codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> $</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> browser </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@wdio/globals"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Key</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"webdriverio"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">describe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"DevTools Test on latest chrome"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">it</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Devtools Navigation"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Open an example game.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token string" style="color:#e3116c">"https://pixijs.io/examples-v5/#/demos-basic/container.js"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Get window handles.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> handles </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getWindowHandles</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Switch to devtools window.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">switchToWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">handles</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Navigate through devtool tabs.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// For linux machines use [Key.Control, '['] .</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">keys</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token maybe-class-name">Key</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access maybe-class-name">Meta</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"["</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Switch to devtool extension iframe.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">switchToFrame</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Manipulate extension.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string" style="color:#e3116c">"body &gt; div &gt; div &gt; div.status.svelte-iqeeoq &gt; div.patch.svelte-iqeeoq &gt; button"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string" style="color:#e3116c">"body &gt; div &gt; div &gt; div.outliner.svelte-iqeeoq &gt; div &gt; div.body.svelte-1vjyr8f &gt; div:nth-child(1) &gt; button:nth-child(4)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string" style="color:#e3116c">"body &gt; div &gt; div &gt; div.outliner.svelte-iqeeoq &gt; div &gt; div.body.svelte-1vjyr8f &gt; div:nth-child(1) &gt; button:nth-child(4)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Switch back to parent frame.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">switchToParentFrame</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Switch back to main window.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">switchToWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">handles</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div><h3 class="anchor anchorTargetStickyNavbar_eDRp" id="explanation-of-the-script">Explanation of the Script<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#explanation-of-the-script" class="hash-link" aria-label="Direkter Link zu Explanation of the Script" title="Direkter Link zu Explanation of the Script" translate="no">​</a></h3><ol>
<li class=""><strong>Open a URL:</strong> The script navigates to an example PixiJS game.</li>
<li class=""><strong>Get Window Handles:</strong> Retrieves the window handles for the main window and the DevTools window.</li>
<li class=""><strong>Switch to DevTools Window:</strong> Switches context to the DevTools window using its handle.</li>
<li class=""><strong>Navigate DevTools Tabs:</strong> Uses keyboard shortcuts to navigate through DevTools tabs. Note: For Linux, replace <code>['Meta', '[']</code> with <code>['Control', '[']</code>.</li>
<li class=""><strong>Switch to Iframe:</strong> Switches to the iframe that contains the PixiJS extension.</li>
<li class=""><strong>Interact with the Extension:</strong> Performs clicks on specific elements within the extension.</li>
<li class=""><strong>Switch Back:</strong> Returns to the parent frame and then back to the main window.</li>
</ol></div><div role="tabpanel" class="tabItem_Y7ux" hidden=""><div class="language-javascript codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-javascript codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> browser </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@wdio/globals"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">describe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Devtools using Puppeteer"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">it</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Devtools Navigation"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Open an example game.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"https://pixijs.io/examples-v5/#/demos-basic/container.js"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Get puppeteer instance from browser</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> puppeteer </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getPuppeteer</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Get all targets from the current window</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> targets </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> puppeteer</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">targets</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Filter all targets and select the one starts from 'devtools://'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> devtoolsTarget </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> targets</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">find</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">t</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> t</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">url</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'devtools://'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Devtools target type is 'other' and we change (we actually hack it) the type to 'page'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// in order to be able to interact with and expose it's DOM</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// NOTE: you can refer to this page https://pptr.dev/api/puppeteer.target.aspage/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> devtoolsPage </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> devtoolsTarget</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">asPage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> devtoolsPage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">bringToFront</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Navigate through Devtools tabs.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// For linux machines use ['Control', '['] .</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> devtoolsPage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">keyboard</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">down</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Meta'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> devtoolsPage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">keyboard</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">press</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'['</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> devtoolsPage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">keyboard</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">up</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Meta'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Get all the iframes from Devtools window related with the current open tab</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> frames </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> devtoolsPage</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">frames</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Switch to devtool extension iframe.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> iframe </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> frames</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Use puppetter commands to execute some expressions directly in the Devtools extensions window</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// NOTE: https://pptr.dev/api/puppeteer.page.evaluate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> iframe</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> xpath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/html/body/div/div/div[2]/div[1]/button'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">xpath</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">XPathResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">FIRST_ORDERED_NODE_TYPE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">singleNodeValue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> iframe</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> xpath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/html/body/div/div/div[1]/div/div[2]/div[1]/button[3]'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">xpath</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">XPathResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">FIRST_ORDERED_NODE_TYPE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">singleNodeValue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> iframe</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> xpath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/html/body/div/div/div[1]/div/div[2]/div[1]/button[3]'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">evaluate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">xpath</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">XPathResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">FIRST_ORDERED_NODE_TYPE</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">singleNodeValue</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pause</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div><h3 class="anchor anchorTargetStickyNavbar_eDRp" id="explanation-of-the-script-1">Explanation of the Script<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#explanation-of-the-script-1" class="hash-link" aria-label="Direkter Link zu Explanation of the Script" title="Direkter Link zu Explanation of the Script" translate="no">​</a></h3><h2 class="anchor anchorTargetStickyNavbar_eDRp" id="overview">Overview<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#overview" class="hash-link" aria-label="Direkter Link zu Overview" title="Direkter Link zu Overview" translate="no">​</a></h2><p>This script performs several actions using Puppeteer to interact with a PixiJS game through the browser's DevTools. The steps involved include opening a URL, retrieving and filtering targets, navigating DevTools tabs, and interacting with a PixiJS extension.</p><h2 class="anchor anchorTargetStickyNavbar_eDRp" id="detailed-steps">Detailed Steps<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#detailed-steps" class="hash-link" aria-label="Direkter Link zu Detailed Steps" title="Direkter Link zu Detailed Steps" translate="no">​</a></h2><ol>
<li class=""><strong>Open a URL:</strong> The script navigates to an example PixiJS game.</li>
<li class=""><strong>Get Puppeteer Instance:</strong> Retrieves the Puppeteer instance from the browser.</li>
<li class=""><strong>Get All Targets:</strong> Retrieves all the targets from the current window. Targets in Puppeteer represent different contexts within the browser, such as pages, iframes, or service workers.</li>
<li class=""><strong>Filter DevTools Target:</strong> Filters the targets to find the one starting with <code>devtools://</code>.</li>
<li class=""><strong>Hack Target Type:</strong> Changes the target type to <code>page</code> to interact with and expose its DOM. This ensures that the target can be manipulated and inspected as a regular web page.</li>
<li class=""><strong>Get DevTools Page:</strong> Retrieves the page, including its DOM, elements, selectors, etc., from the DevTools target. This allows interaction with the elements within DevTools.</li>
<li class=""><strong>Navigate DevTools Tabs:</strong> Uses keyboard shortcuts to navigate through DevTools tabs. On Linux, replace <code>['Control', '[']</code> with <code>['Meta', '[']</code>.</li>
<li class=""><strong>Get All Iframes:</strong> Retrieves all the iframes from the DevTools window related to the current open tab.</li>
<li class=""><strong>Switch to DevTools Extension Iframe:</strong> Switches to the iframe containing the PixiJS extension.</li>
<li class=""><strong>Interact with the Extension:</strong> Uses Puppeteer commands to execute expressions directly in the DevTools extension window. This step facilitates interaction with the PixiJS extension.</li>
</ol></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="running-the-test">Running the Test<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#running-the-test" class="hash-link" aria-label="Direkter Link zu Running the Test" title="Direkter Link zu Running the Test" translate="no">​</a></h2>
<p>To run the test, execute the following command:</p>
<div class="language-sh codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-sh codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">npx wdio run wdio.conf.js</span><br></span></code></pre></div></div>
<p>This will launch Chrome, open the specified URL, interact with the DevTools, and manipulate the PixiJS extension as defined in the test script.</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="demonstration">Demonstration<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#demonstration" class="hash-link" aria-label="Direkter Link zu Demonstration" title="Direkter Link zu Demonstration" translate="no">​</a></h4>
<p><img decoding="async" loading="lazy" alt="Devtools" src="https://webdriver.io/de/assets/images/devtools-71243e3e992a092e5f040f2c004d5f3c.gif" width="600" height="309" class="img_ahPx"></p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="conclusion">Conclusion<a href="https://webdriver.io/de/blog/2024/08/12/manipulate-devtools#conclusion" class="hash-link" aria-label="Direkter Link zu Conclusion" title="Direkter Link zu Conclusion" translate="no">​</a></h2>
<p>By leveraging WebDriverIO and Chrome DevTools, you can automate complex browser interactions and extension manipulations. This approach is beneficial for testing web applications and ensuring extensions like PixiJS work correctly across different scenarios.</p>
<p>Feel free to modify the script to fit your specific testing needs. Happy testing!</p>]]></content>
        <author>
            <name>George Romanas</name>
            <uri>https://github.com/gromanas</uri>
        </author>
        <author>
            <name>Nikos Lytras</name>
            <uri>https://github.com/nikoslytr</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Major Updates to WebdriverIO's Visual Testing Module]]></title>
        <id>https://webdriver.io/de/blog/2024/06/11/major-update-visual-testing</id>
        <link href="https://webdriver.io/de/blog/2024/06/11/major-update-visual-testing"/>
        <updated>2024-06-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are thrilled to announce the latest update to the WebdriverIO Visual Testing module. This release brings two significant enhancements: making the Visual Testing Module a pure JS module and the introduction of a new CLI argument for automatic baseline updates.]]></summary>
        <content type="html"><![CDATA[<p>We are thrilled to announce the latest update to the WebdriverIO Visual Testing module. This release brings two significant enhancements: making the Visual Testing Module a pure JS module and the introduction of a new CLI argument for automatic baseline updates.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="making-the-visual-testing-module-a-pure-js-module">Making The Visual Testing Module a Pure JS module<a href="https://webdriver.io/de/blog/2024/06/11/major-update-visual-testing#making-the-visual-testing-module-a-pure-js-module" class="hash-link" aria-label="Direkter Link zu Making The Visual Testing Module a Pure JS module" title="Direkter Link zu Making The Visual Testing Module a Pure JS module" translate="no">​</a></h3>
<p>One of the major changes in this update is the replacement of the <a href="https://github.com/Automattic/node-canvas" target="_blank" rel="noopener noreferrer" class="">Canvas</a> library with <a href="https://github.com/jimp-dev/jimp" target="_blank" rel="noopener noreferrer" class="">Jimp</a>. This shift eliminates the need for system dependencies, which often cause issues on local machines due to missing dependencies and complicate CI/CD pipelines. By using Jimp, we have streamlined the installation and setup process, making it more straightforward, less prone to errors and more important, a <strong>pure JS module</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="new-cli-argument-for-baseline-updates">New CLI Argument for Baseline Updates<a href="https://webdriver.io/de/blog/2024/06/11/major-update-visual-testing#new-cli-argument-for-baseline-updates" class="hash-link" aria-label="Direkter Link zu New CLI Argument for Baseline Updates" title="Direkter Link zu New CLI Argument for Baseline Updates" translate="no">​</a></h3>
<p>In response to user feedback, we've introduced a new command-line argument that allows you to automatically update your baseline images. This feature simplifies the process of maintaining and updating your baseline images, ensuring your visual regression tests remain accurate and up-to-date with minimal manual intervention. By adding the argument <code>--update-visual-baseline</code> to your command your tests will be executed again and failed tests will automatically be updated.</p>
<p>Learn everything about WebdriverIO's visual testing capabilities in our <a class="" href="https://webdriver.io/de/docs/visual-testing">Visual docs</a> and join our <a href="https://discord.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">👁️-visual-testing</a> channel on Discord.</p>
<p>Thank you for your continued support, and we look forward to your feedback on these new features.</p>
<p>Happy testing!</p>
<p><em>The WebdriverIO Team</em></p>]]></content>
        <author>
            <name>WebdriverIO Team</name>
            <uri>https://x.com/webdriverio</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing DOM and Visual Snapshot Testing for Component, End-to-End and Mobile Testing]]></title>
        <id>https://webdriver.io/de/blog/2024/03/20/snapshot-testing</id>
        <link href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing"/>
        <updated>2024-03-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We're excited to announce support for DOM and Visual snapshot tests using a common set of primitives supporting all testing environments WebdriverIO offers. Our vision has always been to provide a comprehensive, versatile testing tool that simplifies your workflow. This update is a step towards creating a 'Swiss Army Knife' for unit and visual testing, catering to diverse requirements across platforms and extending our support to native mobile applications, making your testing process more efficient and seamless.]]></summary>
        <content type="html"><![CDATA[<p>We're excited to announce support for DOM and Visual snapshot tests using a common set of primitives supporting all testing environments WebdriverIO offers. Our vision has always been to provide a comprehensive, versatile testing tool that simplifies your workflow. This update is a step towards creating a 'Swiss Army Knife' for unit and visual testing, catering to diverse requirements across platforms and extending our support to native mobile applications, making your testing process more efficient and seamless.</p>
<p>Both, DOM and Visual Snapshot primitives will be available for you when running component and unit tests, end-to-end tests as well as mobile web tests. In addition to that the same visual snapshot primitives will be also available for native mobile application tests.</p>
<p>If you are more of a visual learner, we've also released a WebdriverIO tutorial on our <a href="https://youtube.com/@webdriverio" target="_blank" rel="noopener noreferrer" class="">YouTube</a> channel:</p>
<link rel="preload" href="https://i.ytimg.com/vi/wQRGpWX3fsk/hqdefault.jpg" as="image"><article class="yt-lite" data-title="WebdriverIO Tutorials: Snapshot Testing" style="background-image:url(https://i.ytimg.com/vi/wQRGpWX3fsk/hqdefault.jpg);--aspect-ratio:56.25%"><button type="button" class="lty-playbtn" aria-label="Watch WebdriverIO Tutorials: Snapshot Testing"></button></article>
<p>Let's dive into each of these powerful capabilities.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="dom-or-object-snapshots">DOM or Object Snapshots<a href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing#dom-or-object-snapshots" class="hash-link" aria-label="Direkter Link zu DOM or Object Snapshots" title="Direkter Link zu DOM or Object Snapshots" translate="no">​</a></h2>
<p>For evaluating the state of the DOM, a large object or the content of a UI element we often tend to copy the value into our test and manually update it if we change the behavior of our application or component.</p>
<p>With text-based snapshots, we can just have this handled by WebdriverIO. For example, let's say we want to verify the state of our React component in a browser, we can just do the following:</p>
<div class="language-tsx codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">/src/component.test.tsx</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-tsx codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> expect</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> $ </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@wdio/globals'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> render </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@testing-library/react'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">App</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">theme</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> setTheme</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">useState</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'light'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">toggleTheme</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> nextTheme </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> theme </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'light'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'dark'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'light'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">setTheme</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nextTheme</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">button</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">onClick</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">toggleTheme</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text">        Current theme: </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">theme</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">button</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">describe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'React Component Testing'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">it</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'supports snapshot tests'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> container </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">App</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">container</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toMatchSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'button'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">container</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toMatchSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>WebdriverIO will automatically grab the DOM structure of the component and store a snapshot file called <code>component.test.tsx.snap</code> in <code>/src/__snapshots__</code> directory next to your test with the following content:</p>
<div class="language-text codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-text codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">// Snapshot v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">exports[`React Component Testing &gt; supports snapshot tests 1`] = `"&lt;div&gt;&lt;button&gt;Current theme: light&lt;/button&gt;&lt;/div&gt;"`;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">exports[`React Component Testing &gt; supports snapshot tests 2`] = `"&lt;div&gt;&lt;button&gt;Current theme: dark&lt;/button&gt;&lt;/div&gt;"`;</span><br></span></code></pre></div></div>
<p>If you prefer to keep the snapshots as part of your tests you can use <code>toMatchInlineSnapshot</code> instead:</p>
<div class="language-tsx codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-tsx codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">container</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toMatchInlineSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>After running the test for the first time, WebdriverIO will make a change to the test and fill in the snapshot inline:</p>
<div class="language-tsx codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-tsx codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">container</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toMatchInlineSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">"&lt;div&gt;&lt;button&gt;Current theme: light&lt;/button&gt;&lt;/div&gt;"</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Now, if you make changes to your component that will impact all snapshots you can update them all in a single run by calling:</p>
<div class="language-sh codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-sh codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">npx wdio run wdio.conf.ts --updateSnapshots</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># or</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">npx wdio run wdio.conf.ts -s</span><br></span></code></pre></div></div>
<p>This makes maintaining your tests so much easier. The same works for all other types of objects, e.g. CSS Properties, or the text content of an element. They all can be converted into a snapshot to simplify the assertion and keep your tests lean. This can also speed up your tests by merging many single assertions into one, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> elem </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#alertBar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elem</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveAttribute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'data-alert'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elem</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveClassName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'success'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elem</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'You logged into a secure area!'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>now becomes a single:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#alertBar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * stores the following into a snapshot file:</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * &lt;div data-alert="" id="flash" class="flash success"&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *   You logged into a secure area!</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *   &lt;a href="#" class="close"&gt;×&lt;/a&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * &lt;/div&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><br></span></code></pre></div></div>
<p>While taking a snapshot of the DOM might be the most prominent use case, you can take snapshots of all types of serializable data structures, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// the visible content of an element</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'elem'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// or of an serializable object</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'elem'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getCSSProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'color'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>You can find more information about DOM and object-based snapshots in our <a class="" href="https://webdriver.io/de/docs/snapshot">Snapshot guide</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="visual-snapshots">Visual Snapshots<a href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing#visual-snapshots" class="hash-link" aria-label="Direkter Link zu Visual Snapshots" title="Direkter Link zu Visual Snapshots" translate="no">​</a></h2>
<p>While taking snapshots of an element structure and its attributes might be great and powerful, it comes with an important caveat: even though we are testing that the element has a class name called <code>success</code>, this doesn't guarantee that the alert is green!</p>
<p>For these reasons, visual testing has become a very popular tool as it includes how elements are rendered, in which color and can ensure that e.g. it is not overlaid by any other element. Taking visual snapshots works very similarly, as you can:</p>
<ul>
<li class="">take a visual snapshot of the whole screen:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">browser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchScreenSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'partialPage'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">take a visual snapshot of an element:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#element-id'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchElementSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'firstButtonElement'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">take a snapshot of the whole page:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">browser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchFullPageSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'fullPage'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">or take a page snapshot that includes <a href="https://vivrichards.co.uk/accessibility/automating-page-tab-flows-using-visual-testing-and-javascript" target="_blank" rel="noopener noreferrer" class="">page tab-ability</a>:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">browser</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toMatchTabbablePageSnapshot</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'check-tabbable'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
</ul>
<p>WebdriverIO will store these visual snapshots conveniently next to your text-based snapshots within the <code>__snapshots__</code> directory next to your test.</p>
<p>While text-based snapshot testing is built into WebdriverIO, you have to install a <a href="https://www.npmjs.com/package/@wdio/visual-service" target="_blank" rel="noopener noreferrer" class="">service</a> to enable all visual snapshot capabilities via:</p>
<div class="language-sh codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-sh codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">npm i --save-dev @wdio/visual-service</span><br></span></code></pre></div></div>
<p>With the most recent release of the Visual Testing Module with have shipped further improvements for <strong>Mobile Native App Snapshot Testing</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="mobile-native-app-snapshot-testing">Mobile Native App Snapshot Testing<a href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing#mobile-native-app-snapshot-testing" class="hash-link" aria-label="Direkter Link zu Mobile Native App Snapshot Testing" title="Direkter Link zu Mobile Native App Snapshot Testing" translate="no">​</a></h3>
<p>The module now supports the <code>toMatchElementSnapshot</code> and <code>toMatchScreenSnapshot</code> matchers for Mobile native apps. It automatically detects the testing context (web, webview, or native_app) to streamline your workflow.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="key-features-of-the-visual-service">Key Features of the Visual Service<a href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing#key-features-of-the-visual-service" class="hash-link" aria-label="Direkter Link zu Key Features of the Visual Service" title="Direkter Link zu Key Features of the Visual Service" translate="no">​</a></h3>
<p>Some of the features that make visual testing with WebdriverIO unique are:</p>
<ul>
<li class="">save or compare <strong>screens/elements/full-page</strong> screens against a baseline</li>
<li class="">automatically <strong>create a baseline</strong> when no baseline is there</li>
<li class=""><strong>block out custom regions</strong> and even <strong>automatically exclude</strong> a status and or toolbars (mobile only) during a comparison</li>
<li class="">increase the element dimensions screenshots</li>
<li class=""><strong>hide text</strong> during website comparison to:<!-- -->
<ul>
<li class=""><strong>improve stability</strong> and prevent font rendering flakiness</li>
<li class="">only focus on the <strong>layout</strong> of a website</li>
</ul>
</li>
<li class="">use <strong>different comparison methods</strong> and a set of <strong>additional matchers</strong> for better readable tests</li>
<li class="">verify how your website will <strong>support tabbing with your keyboard</strong>, see also <a class="" href="https://webdriver.io/de/docs/visual-testing#tabbing-through-a-website">Tabbing through a website</a></li>
<li class="">and much more, see the <a class="" href="https://webdriver.io/de/docs/visual-testing/service-options">service</a> and <a class="" href="https://webdriver.io/de/docs/visual-testing/method-options">method</a> options</li>
</ul>
<p>Learn everything about WebdriverIO's visual testing capabilities in our <a class="" href="https://webdriver.io/de/docs/visual-testing">Visual docs</a> and join our <a href="https://discord.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">👁️-visual-testing</a> channel on Discord.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="special-thanks-to-wswebcreation">Special Thanks to <a href="https://github.com/wswebcreation" target="_blank" rel="noopener noreferrer" class=""><code>@wswebcreation</code></a><a href="https://webdriver.io/de/blog/2024/03/20/snapshot-testing#special-thanks-to-wswebcreation" class="hash-link" aria-label="Direkter Link zu special-thanks-to-wswebcreation" title="Direkter Link zu special-thanks-to-wswebcreation" translate="no">​</a></h3>
<p>We owe a big thank you to our core maintainer <a href="https://github.com/wswebcreation" target="_blank" rel="noopener noreferrer" class="">Wim Selles</a> for his work in <a href="https://github.com/wswebcreation/wdio-native-app-compare" target="_blank" rel="noopener noreferrer" class=""><code>wdio-native-app-compare</code></a>, which inspired this enhancement. His contribution has been vital in advancing our module's capabilities.</p>
<p>Thank you for your continued support, and we look forward to your feedback on these new features.</p>
<p>Happy testing!</p>
<p><em>The WebdriverIO Team</em></p>]]></content>
        <author>
            <name>WebdriverIO Team</name>
            <uri>https://x.com/webdriverio</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[A New Contributor Stipend Program for WebdriverIO]]></title>
        <id>https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program</id>
        <link href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program"/>
        <updated>2024-02-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The WebdriverIO community is on the verge of an exciting new era, supported by strategic partnerships with BrowserStack and Sauce Labs, along with continuous support from other sponsors like TestMu AI (Formerly LambdaTest). This collective endeavor signifies a crucial milestone for the WebdriverIO project, as we utilize these additional resources to foster the growth and enrichment of our ecosystem.]]></summary>
        <content type="html"><![CDATA[<p>The WebdriverIO community is on the verge of an exciting new era, supported by strategic partnerships with <a href="https://www.browserstack.com/" target="_blank" rel="noopener noreferrer" class="">BrowserStack</a> and <a href="https://saucelabs.com/" target="_blank" rel="noopener noreferrer" class="">Sauce Labs</a>, along with continuous support from other sponsors like <a href="https://www.testmuai.com/" target="_blank" rel="noopener noreferrer" class="">TestMu AI (Formerly LambdaTest)</a>. This collective endeavor signifies a crucial milestone for the WebdriverIO project, as we utilize these additional resources to foster the growth and enrichment of our ecosystem.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="towards-a-sustainable-open-source-model">Towards a Sustainable Open Source Model<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#towards-a-sustainable-open-source-model" class="hash-link" aria-label="Direkter Link zu Towards a Sustainable Open Source Model" title="Direkter Link zu Towards a Sustainable Open Source Model" translate="no">​</a></h2>
<p>WebdriverIO's story began with its inception into the JS Foundation in 2017, which later evolved into the OpenJS Foundation. Since then, it has thrived as an open-governed, community-driven endeavor, witnessing continuous growth in NPM downloads, the introduction of innovative plugins and reporters, and the rollout of new functionalities. This expansion is a testament to the hard work and dedication of the global testing community, including project users and contributors from leading testing cloud providers.</p>
<p>WebdriverIO's core principle is its dedication to open governance, an aspect that has attracted the trust and confidence of its users, especially those in the enterprise world. The project's growth has been organic, independent of Venture Capital, corporate objectives and sales requirements, guaranteeing that its development aligns with the true needs of our user community and all features remain free of charge.</p>
<p>With the project's continuous expansion, marked by increasing NPM downloads, new functionalities, plugins, and reporters, the importance of nurturing a healthy and sustainable growth path has never been more critical. Our recent alliances with top cloud services for automated testing demonstrate our dedication to responsibly managing these resources, with the aim to widen our network of contributors and enrich the entire ecosystem.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="introducing-the-stipend-program">Introducing the Stipend Program<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#introducing-the-stipend-program" class="hash-link" aria-label="Direkter Link zu Introducing the Stipend Program" title="Direkter Link zu Introducing the Stipend Program" translate="no">​</a></h2>
<p>Central to our ethos is the belief that financial support of the WebdriverIO ecosystem is a worthy endeavor.  Whether it's the occasional contributions from casual participants or the continuous dedication of our core team members, every contribution is a building block of our project's success. Currently, the project benefits from a monthly donation inflow of <code>$3,879</code>, sourced through various channels like <a href="https://tidelift.com/subscription/pkg/npm-webdriverio?utm_source=npm-webdriverio&amp;utm_medium=github_sponsor_button" target="_blank" rel="noopener noreferrer" class="">Tidelift</a>, <a href="https://thanks.dev/" target="_blank" rel="noopener noreferrer" class="">Thanks.dev</a>, <a href="https://github.com/sponsors/webdriverio" target="_blank" rel="noopener noreferrer" class="">GitHub Sponsors</a>, and our <a href="https://opencollective.com/webdriverio" target="_blank" rel="noopener noreferrer" class="">Open Collective</a>. These funds have empowered the Technical Steering Committee to finalize new <a href="https://github.com/webdriverio/webdriverio/blob/main/GOVERNANCE.md#allocation-of-funds" target="_blank" rel="noopener noreferrer" class="">governance policies</a>, outlining our strategic approach to fund allocation.</p>
<p>Our monthly budget is allocated across four key areas:</p>
<ul>
<li class="">Project Development receives the largest share, with 60% of the funds dedicated to fostering growth and innovation.</li>
<li class="">Travel and Event Expenses account for 20%, supporting our participation in and hosting of industry events and meetups.</li>
<li class="">Support Systems are allocated 10% of the budget, ensuring our infrastructure and community support mechanisms remain robust.</li>
<li class="">Lastly, Dependencies, crucial external projects and tools we rely on, also receive 10% of our financial resources.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="dedication-to-project-development">Dedication to Project Development<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#dedication-to-project-development" class="hash-link" aria-label="Direkter Link zu Dedication to Project Development" title="Direkter Link zu Dedication to Project Development" translate="no">​</a></h3>
<p>Our financial strategy gives top priority to project development, dedicating 60% of our resources to it. This funding aims to draw contributions from a wide range of people, increasing our base of dedicated contributors. By dividing the funds, allocating 35% to individuals not directly involved with the project and 65% to our project contributors and the Technical Steering Committee (TSC) members, we seek to foster a strong sense of community and shared ownership. This approach is vital for ensuring the long-term prosperity and stability of our project.</p>
<p>As part of this strategy, we have developed an automated expense process using a <a href="https://github.com/webdriverio/expense-action" target="_blank" rel="noopener noreferrer" class="">GitHub Action</a> to help run this program. You can read more about how this process works on my <a href="https://bromann.dev/post/automated-contributor-expense-process/" target="_blank" rel="noopener noreferrer" class="">personal blog</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="supporting-community-engagement-and-events">Supporting Community Engagement and Events<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#supporting-community-engagement-and-events" class="hash-link" aria-label="Direkter Link zu Supporting Community Engagement and Events" title="Direkter Link zu Supporting Community Engagement and Events" translate="no">​</a></h3>
<p>Recognizing the importance of community engagement, especially in the aftermath of Covid-19, we are allocating funds towards travel and event expenses. This decision emphasizes our commitment to creating user meetups and supporting the broader community in hosting WebdriverIO-related events. It reflects our desire to not only maintain but also to strengthen the community ties that form the backbone of our project.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="enhancing-support-systems">Enhancing Support Systems<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#enhancing-support-systems" class="hash-link" aria-label="Direkter Link zu Enhancing Support Systems" title="Direkter Link zu Enhancing Support Systems" translate="no">​</a></h3>
<p>A small fraction of our monthly budget is allocated to various essentials that support our project's community growth and upkeep. Our intention is to invest in translating our documentation and financially support those who contribute to this effort. Additionally, we aim to cover ongoing costs for infrastructure needed to host project-related materials, as well as provide our maintainers with the software tools necessary to enhance their contributions to the project.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="acknowledging-dependencies">Acknowledging Dependencies<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#acknowledging-dependencies" class="hash-link" aria-label="Direkter Link zu Acknowledging Dependencies" title="Direkter Link zu Acknowledging Dependencies" translate="no">​</a></h3>
<p>Finally, we're committed to giving back to the projects and communities that are crucial to WebdriverIO's success. We believe it's vital for open-source projects benefiting from generous donations to support their key dependencies. Thanks to <a href="https://thanks.dev/" target="_blank" rel="noopener noreferrer" class="">Thanks.dev</a>, we can identify and financially support our most critical dependencies based on their significance to our project and the funds we allocate monthly for this purpose. Noteworthy dependencies include:</p>
<ul>
<li class="">Individual open-source champions like <a href="https://opencollective.com/sindresorhus" target="_blank" rel="noopener noreferrer" class="">Sindre Sorhus</a> and <a href="https://github.com/sponsors/isaacs" target="_blank" rel="noopener noreferrer" class="">isaacs</a>, whose contributions to various dependencies are invaluable.</li>
<li class="">The Vite ecosystem: we use <a href="https://vitest.dev/" target="_blank" rel="noopener noreferrer" class="">Vitest</a> across almost all our projects, and we couldn't provide such powerful component testing capabilities without <a href="https://vitejs.dev/" target="_blank" rel="noopener noreferrer" class="">Vite</a> under the hood</li>
<li class="">The <a href="https://opencollective.com/eslint" target="_blank" rel="noopener noreferrer" class="">Eslint</a> project and its related <a href="https://opencollective.com/typescript-eslint" target="_blank" rel="noopener noreferrer" class="">ecosystem projects</a> are fundamental to maintaining a high code quality of our projects and have significantly <a href="https://eslint.org/blog/2022/02/paying-contributors-sponsoring-projects/" target="_blank" rel="noopener noreferrer" class="">inspired</a> our contributor stipend program.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="looking-ahead">Looking Ahead<a href="https://webdriver.io/de/blog/2024/02/15/new-contributor-stipend-program#looking-ahead" class="hash-link" aria-label="Direkter Link zu Looking Ahead" title="Direkter Link zu Looking Ahead" translate="no">​</a></h2>
<p>As we embrace this new chapter, we're excited about the prospects of accelerating growth through strategic investments in our community and project. The early feedback from our initiatives has been <a href="https://twitter.com/vobu/status/1755560452015157273" target="_blank" rel="noopener noreferrer" class="">overwhelmingly positive</a>, and we are committed to refining our processes for even greater efficiency and transparency.</p>
<p align="center"><img src="https://webdriver.io/img/blog/vobu.png" alt="Twitter Excitement"></p>
<p>We extend our heartfelt gratitude to our sponsors for their invaluable support, and we warmly welcome <a href="https://opencollective.com/webdriverio" target="_blank" rel="noopener noreferrer" class="">further sponsorship</a> to join us in this journey. Together, we are setting the stage for an even brighter future for WebdriverIO and its thriving ecosystem.</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Sauce Labs joins WebdriverIOs Partnership Program as Premium Sponsor]]></title>
        <id>https://webdriver.io/de/blog/2024/02/05/saucelabs-partnership</id>
        <link href="https://webdriver.io/de/blog/2024/02/05/saucelabs-partnership"/>
        <updated>2024-02-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are thrilled to announce an exciting development in our journey towards innovation in software testing and quality assurance. Sauce Labs, a pioneering force in the continuous testing arena, is joining forces with us through our Partnership Program. This collaboration marks a significant milestone in our quest to expand our development fund, enabling us to enhance our work on major releases and introduce groundbreaking features yet to be unveiled.]]></summary>
        <content type="html"><![CDATA[<p>We are thrilled to announce an exciting development in our journey towards innovation in software testing and quality assurance. <a href="https://saucelabs.com/" target="_blank" rel="noopener noreferrer" class="">Sauce Labs</a>, a pioneering force in the continuous testing arena, is joining forces with us through our Partnership Program. This collaboration marks a significant milestone in our quest to expand our development fund, enabling us to enhance our work on major releases and introduce groundbreaking features yet to be unveiled.</p>
<p align="center"></p>
<p>Sauce Labs has earned a reputation as a leader in providing solutions that empower organizations worldwide to achieve excellence in software delivery. Their platform, trusted by thousands of development teams, ensures that digital products function seamlessly across every browser, operating system, and device. This commitment to quality guarantees a flawless user experience, showcasing Sauce Labs' dedication to software excellence.</p>
<p>The company has been technically sponsoring the project almost since day one. My early work on WebdriverIO has opened an opportunity to work at Sauce Labs and during my 7-year tenure there, I was allowed and encouraged to work on this framework. Even some of Sauce Labs products have been heavily inspired by the work in WebdriverIO, e.g. their <a href="https://www.youtube.com/watch?v=rP-j9uPPbt8" target="_blank" rel="noopener noreferrer" class="">performance testing</a> and <a href="https://www.youtube.com/watch?v=pkWv-JIf4eo" target="_blank" rel="noopener noreferrer" class="">extended debugging</a> capabilities.</p>
<p>It makes me personally very happy to see Sauce Labs staying invested in the Open-Source testing ecosystem. Being the originators of <a href="https://www.selenium.dev/" target="_blank" rel="noopener noreferrer" class="">Selenium</a> and creators of <a href="https://appium.io/" target="_blank" rel="noopener noreferrer" class="">Appium</a> Sauce Labs remains a strong supporter of open-governed tools like WebdriverIO.</p>
<p>Thank you 🙏</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Exciting Partnership Announcement: WebdriverIO Teams Up with BrowserStack]]></title>
        <id>https://webdriver.io/de/blog/2024/01/29/browserstack-partnership</id>
        <link href="https://webdriver.io/de/blog/2024/01/29/browserstack-partnership"/>
        <updated>2024-01-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are thrilled to share some fantastic news: WebdriverIO and BrowserStack have embarked on a groundbreaking partnership, set to significantly boost the development and community engagement of our project!]]></summary>
        <content type="html"><![CDATA[<p>We are thrilled to share some fantastic news: WebdriverIO and <a href="https://browserstack.com/" target="_blank" rel="noopener noreferrer" class="">BrowserStack</a> have embarked on a groundbreaking partnership, set to significantly boost the development and community engagement of our project!</p>
<p align="center"></p>
<p>BrowserStack is the world’s leading software testing platform powering over two million tests every day across 15 global data centers. BrowserStack helps Tesco, Shell, NVIDIA, Discovery, Wells Fargo, and over 50,000 customers deliver quality software at speed by moving testing to their Cloud. BrowserStack’s platform provides instant access to 3,000+ real mobile devices and browsers on a highly reliable cloud infrastructure that effortlessly scales as testing needs grow. With BrowserStack, Dev and QA teams can move fast while delivering an amazing experience for every customer.</p>
<p>In an exciting turn, BrowserStack has become an exclusive Premium Sponsor for WebdriverIO, providing crucial funding that supplements our primarily user-generated donations. This generous support enables us to advance significant initiatives, including our upcoming major release. For the first time, we can offer financial recognition to our devoted community contributors, acknowledging their invaluable efforts toward the project's triumph. We will soon share more information on how we will use the project funds and how we plan to distribute them.</p>
<p>As a token of this collaboration, BrowserStack is extending a special free trial license to all WebdriverIO users. Discover more about this incredible offer at <a href="https://www.browserstack.com/automation-webdriverio" target="_blank" rel="noopener noreferrer" class="">browserstack.com</a>.</p>
<p>Since its inception, WebdriverIO has been propelled by a dedicated group of developers, united by a passion for crafting tools that enhance software quality. While other testing projects have benefited from substantial venture capital and corporate funding, WebdriverIO has predominantly relied on its vibrant community, without the means to provide significant financial compensation for contributions.</p>
<p>The <a href="https://github.com/webdriverio/webdriverio/blob/main/AUTHORS.md" target="_blank" rel="noopener noreferrer" class="">core contributors</a> of WebdriverIO are elated about this partnership. We are profoundly grateful to BrowserStack for their commitment to nurturing open-governed, open-source projects like ours.</p>
<p>Thank you 🙏</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Enhanced Test Automation with WebdriverIO]]></title>
        <id>https://webdriver.io/de/blog/2024/01/18/enhanced-test-automation-with-webdriverio</id>
        <link href="https://webdriver.io/de/blog/2024/01/18/enhanced-test-automation-with-webdriverio"/>
        <updated>2024-01-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Embark on a transformative journey into the dynamic landscape of test automation with the compelling and instructive guide, "Enhanced Test Automation with WebdriverIO - Unlock the Superpowers of Hybrid Testing Frameworks." Authored with the dual purpose of empowering both newcomers and seasoned developers, this comprehensive book serves as an indispensable manual for mastering advanced WebdriverIO concepts, specifically tailored for end-to-end testing of web applications.]]></summary>
        <content type="html"><![CDATA[<p>Embark on a transformative journey into the dynamic landscape of test automation with the compelling and instructive guide, "Enhanced Test Automation with WebdriverIO - Unlock the Superpowers of Hybrid Testing Frameworks." Authored with the dual purpose of empowering both newcomers and seasoned developers, this comprehensive book serves as an indispensable manual for mastering advanced WebdriverIO concepts, specifically tailored for end-to-end testing of web applications.</p>
<p><img decoding="async" loading="lazy" alt="Enhanced Test Automation with WebdriverIO" src="https://webdriver.io/de/assets/images/Cover-0e11908c96d9533057af732392297a7c.png" width="203" height="250" class="img_ahPx"></p>
<p>The book's rich content includes insights into the implementation of custom command wrappers and the integration of AI-powered self-healing object strategies, elevating the scope of test automation to unprecedented levels. Its target audience spans Software Developer Engineers in Test (SDETs) seeking to enhance their skill set. By addressing crucial aspects such as dynamic data handling, detailed reporting, and the seamless integration of automated tests into CI/CD pipelines, the book proves particularly beneficial for those striving to streamline test maintenance and automate complex test scenarios.</p>
<p>At the heart of this narrative is WebdriverIO, a leading automation testing framework. As readers navigate through the pages, they are introduced to the art of seamlessly integrating and balancing the strengths of various testing frameworks. The book strategically delves into the intricate realm of hybrid testing, demonstrating how the harmonious synergy of different frameworks can substantially enhance efficiency and reliability in the testing process.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="heres-a-glimpse-into-what-readers-will-uncover">Here's a glimpse into what readers will uncover:<a href="https://webdriver.io/de/blog/2024/01/18/enhanced-test-automation-with-webdriverio#heres-a-glimpse-into-what-readers-will-uncover" class="hash-link" aria-label="Direkter Link zu Here's a glimpse into what readers will uncover:" title="Direkter Link zu Here's a glimpse into what readers will uncover:" translate="no">​</a></h3>
<ol>
<li class="">
<p>Efficient Page Object Model Maintenance:
Discover techniques that empower you to efficiently maintain and enhance your Page Object Model, saving valuable time and effort in the long run.</p>
</li>
<li class="">
<p>Diagnosing and Resolving Script Instability:
Gain insightful strategies for diagnosing and resolving script instability issues, ensuring a consistent and reliable test execution.</p>
</li>
<li class="">
<p>Building Resilient Test Objects:
Learn how to build objects that exhibit adaptability to changing element locators, enhancing the overall resilience of your tests.</p>
</li>
<li class="">
<p>Enhancing Testing Productivity with TypeScript:
Elevate your testing productivity by mastering the art of writing effective test cases with TypeScript, a powerful scripting language.</p>
</li>
<li class="">
<p>Comprehensive Result Analysis for Data-Driven Decision-Making:
Explore strategies for conducting comprehensive result analysis, empowering data-driven decision-making processes within your testing framework.</p>
</li>
<li class="">
<p>Developing Adaptive Frameworks:
Develop frameworks that seamlessly adapt to the evolving user journeys, ensuring the long-term sustainability of your tests.</p>
</li>
</ol>
<p>Packed with practical examples, real-world scenarios, and expert insights, "Enhanced Test Automation with WebdriverIO" goes beyond traditional boundaries, equipping readers with the knowledge to revolutionize their test automation strategies. Whether you are a novice venturing into the automation journey or a seasoned professional looking to amplify your skills, this book serves as your gateway to unlocking the superpowers inherent in hybrid testing frameworks. Embrace the future of test automation and elevate your testing prowess with WebdriverIO.</p>
<p>You can get a copy of this book on <a href="https://www.amazon.com/Enhanced-Test-Automation-WebdriverIO-superpowers/dp/1837630186" target="_blank" rel="noopener noreferrer" class="">Amazon</a> today!</p>]]></content>
        <author>
            <name>Larry Goddard</name>
            <uri>https://linkedin.com/in/larryg</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Take a seat, WebdriverIO is driving for you!]]></title>
        <id>https://webdriver.io/de/blog/2023/07/31/driver-management</id>
        <link href="https://webdriver.io/de/blog/2023/07/31/driver-management"/>
        <updated>2023-07-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Since its inception, WebdriverIO has been a powerful tool for automating browsers through the WebDriver protocol. As many of you know, WebDriver is the web standard for automating real browsers, not just browser engines, allowing you to closely simulate the environment used by your users and customers.]]></summary>
        <content type="html"><![CDATA[<p>Since its inception, WebdriverIO has been a powerful tool for automating browsers through the <a href="https://w3c.github.io/webdriver/" target="_blank" rel="noopener noreferrer" class="">WebDriver</a> protocol. As many of you know, WebDriver is the web standard for automating real browsers, not just browser engines, allowing you to closely simulate the environment used by your users and customers.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="simplified-browser-automation-setup">Simplified Browser Automation Setup<a href="https://webdriver.io/de/blog/2023/07/31/driver-management#simplified-browser-automation-setup" class="hash-link" aria-label="Direkter Link zu Simplified Browser Automation Setup" title="Direkter Link zu Simplified Browser Automation Setup" translate="no">​</a></h2>
<p>To automate a browser, you need to set up a browser driver that translates WebDriver-based commands and executes them within the browser. While WebdriverIO has provided useful services like <a href="https://github.com/webdriverio-community/wdio-chromedriver-service" target="_blank" rel="noopener noreferrer" class=""><code>wdio-chromedriver-service</code></a> to simplify test environment setup, there have been challenges, particularly when new Chrome versions are released 🙈.</p>
<div style="width:100%"><div style="height:0;padding-bottom:56.25%;position:relative;width:100%"><iframe allowfullscreen="" frameborder="0" height="100%" src="https://giphy.com/embed/xuaqgqXadAyg6ZUXHF/video" style="left:0;position:absolute;top:0" width="100%"></iframe></div></div>
<br>
<p><strong>But fear not!</strong> With the release of WebdriverIO version v8.14.0, and onwards, all driver management hassles are now a thing of the past 🙌. The WebdriverIO team has been hard at work, taking over the maintenance of <a href="https://www.npmjs.com/package/geckodriver" target="_blank" rel="noopener noreferrer" class=""><code>geckodriver</code></a>, <a href="https://www.npmjs.com/package/edgedriver" target="_blank" rel="noopener noreferrer" class=""><code>edgedriver</code></a> and <a href="https://www.npmjs.com/package/safaridriver" target="_blank" rel="noopener noreferrer" class=""><code>safaridriver</code></a> packages. This means smoother and more seamless browser automation experiences for you.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="say-goodbye-to-driver-services">Say Goodbye to Driver Services<a href="https://webdriver.io/de/blog/2023/07/31/driver-management#say-goodbye-to-driver-services" class="hash-link" aria-label="Direkter Link zu Say Goodbye to Driver Services" title="Direkter Link zu Say Goodbye to Driver Services" translate="no">​</a></h2>
<p>One of the significant advantages of this update is that you can now get rid of any driver services you previously had to manage, such as <code>wdio-chromedriver-service</code>, <code>wdio-geckodriver-service</code>, <code>wdio-edgedriver-service</code>, <code>wdio-safaridriver-service</code>, and even <code>@wdio/selenium-standalone-service</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="specifying-browser-versions-made-easy">Specifying Browser Versions Made Easy<a href="https://webdriver.io/de/blog/2023/07/31/driver-management#specifying-browser-versions-made-easy" class="hash-link" aria-label="Direkter Link zu Specifying Browser Versions Made Easy" title="Direkter Link zu Specifying Browser Versions Made Easy" translate="no">​</a></h2>
<p>Testing Chrome locally is now more convenient than ever. You can define a browser channel, and WebdriverIO will take care of downloading the specified browser version for you. For example:</p>
<div class="language-js codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-js codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">browserName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'chrome'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">browserVersion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'116.0.5793.0'</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// or 'stable', 'beta', 'dev' or 'canary'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>This has been made possible through Google's effort on <a href="https://developer.chrome.com/blog/chrome-for-testing/" target="_blank" rel="noopener noreferrer" class="">Chrome for Testing</a> which offers reliable downloads for browser automation. It's now built into WebdriverIO and guarantees consistent, reproducible results across repeated test runs.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="effortless-testing-on-microsoft-edge-and-safari">Effortless Testing on Microsoft Edge and Safari<a href="https://webdriver.io/de/blog/2023/07/31/driver-management#effortless-testing-on-microsoft-edge-and-safari" class="hash-link" aria-label="Direkter Link zu Effortless Testing on Microsoft Edge and Safari" title="Direkter Link zu Effortless Testing on Microsoft Edge and Safari" translate="no">​</a></h2>
<p>WebdriverIO will now automatically detect the installed version of Microsoft Edge and download the appropriate Edgedriver for you. Similarly, testing on <a href="https://developer.apple.com/safari/technology-preview/" target="_blank" rel="noopener noreferrer" class="">Safari Technology Preview</a> is a breeze; just install it on your Mac machine and use <code>Safari Technology Preview</code> as the browser name.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="customization-and-flexibility">Customization and Flexibility<a href="https://webdriver.io/de/blog/2023/07/31/driver-management#customization-and-flexibility" class="hash-link" aria-label="Direkter Link zu Customization and Flexibility" title="Direkter Link zu Customization and Flexibility" translate="no">​</a></h2>
<p>For those who require custom driver options, fear not; WebdriverIO allows you to pass in driver options through custom WebdriverIO <a class="" href="https://webdriver.io/de/docs/capabilities/#webdriverio-capabilities-to-manage-browser-driver-options">capabilities</a>. If you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebdriverIO will only start a driver when there are no other connection information settings like  <a class="" href="https://webdriver.io/de/docs/configuration#hostname"><code>hostname</code></a> or <a class="" href="https://webdriver.io/de/docs/configuration#port"><code>port</code></a> specified.</p>
<p>In conclusion, WebdriverIO version <code>v8.14.0</code> and beyond provides an incredibly smooth and seamless browser automation experience. With automated driver management, simplified browser version setup, and improved compatibility, your testing workflows are now more efficient and straightforward than ever before. Say goodbye to the bumpy automation rides and embrace the future of effortless browser testing with WebdriverIO! 🚀</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[TypeScript Support for WebDriver Bidi]]></title>
        <id>https://webdriver.io/de/blog/2023/06/08/bidi-typescript-support</id>
        <link href="https://webdriver.io/de/blog/2023/06/08/bidi-typescript-support"/>
        <updated>2023-06-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[With the release of WebdriverIO v8 we introduced the ability to connect with the WebDriver Bidi protocol directly. This allowed users to access the new capabilities of the protocol in a rudimental way as its development progresses. Today, with every browser release more capabilities will be enabled, so it is time for WebdriverIO to step up its integration and make these easier accessible to the user.]]></summary>
        <content type="html"><![CDATA[<p>With the release of WebdriverIO v8 we introduced the ability to connect with the <a href="https://w3c.github.io/webdriver-bidi/" target="_blank" rel="noopener noreferrer" class="">WebDriver Bidi</a> protocol directly. This allowed users to access the new capabilities of the protocol in a rudimental way as its development progresses. Today, with every browser release more capabilities will be enabled, so it is time for WebdriverIO to step up its integration and make these easier accessible to the user.</p>
<p>With the release of WebdriverIO v8.11 we are adding new WebDriver Bidi interfaces and make them type safe 🎉</p>
<p>The interface of the WebDriver Bidi <a href="https://w3c.github.io/webdriver-bidi/" target="_blank" rel="noopener noreferrer" class="">specification</a> is defined through a <a href="https://www.rfc-editor.org/rfc/rfc8610.html" target="_blank" rel="noopener noreferrer" class="">Concise Data Definition Language</a> (short CDDL). It describes which payloads can be send to the driver and which responses are expected. Over the last month I've been working on a CDDL parser to help the <a href="https://www.w3.org/groups/wg/browser-tools-testing" target="_blank" rel="noopener noreferrer" class="">Browser Testing and Tools Working Group</a> at W3C to validate the CDDL defined in the specification as well as help the WebDriver ecosystem to adopt the protocol.</p>
<p>I've created two NPM packages that hopefully can contribute to that:</p>
<ul>
<li class=""><a href="https://www.npmjs.com/package/cddl" target="_blank" rel="noopener noreferrer" class="">cddl</a>: a package to read CDDL and parse it into an AST as well as validate the contents</li>
<li class=""><a href="https://www.npmjs.com/package/cddl2ts" target="_blank" rel="noopener noreferrer" class="">cddl2ts</a>: a package that allows you to transform a CDDL file into a TypeScript interface that you can use for other TypeScript projects</li>
</ul>
<p>With some recent changes in the WebdriverIO repository we now generate a perfectly typed WebDriver Bidi interface thanks to those packages, e.g.</p>
<p><img decoding="async" loading="lazy" alt="WebDriver Bidi TypeScript Support" src="https://webdriver.io/de/assets/images/bidi-391d6b013db2523eaa3e6fc328770239.png" width="1874" height="1234" class="img_ahPx"></p>
<p>We also updated the <a class="" href="https://webdriver.io/de/docs/api/webdriverBidi">protocol docs</a> to include new Bidi commands that help users to interact with the protocol using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener noreferrer" class="">Promises</a>. As browser start to support more Bidi features WebdriverIO will start running more automation on the new protocol, ensuring that your tests use the latest and greatest cross browser automation standards. Here are some features that are about to land in upcoming browser versions:</p>
<ul>
<li class=""><a href="https://w3c.github.io/webdriver-bidi/#command-script-addPreloadScript" target="_blank" rel="noopener noreferrer" class=""><strong>Add Preload-Scripts</strong></a>: this will be an invaluable command to help WebdriverIO mock Web APIs and inject scripts for introspection</li>
<li class=""><a href="https://github.com/w3c/webdriver-bidi/pull/429" target="_blank" rel="noopener noreferrer" class=""><strong>Network Interception</strong></a>: this will make WebdriverIOs mock API for network requests compatible cross browser</li>
<li class=""><a href="https://github.com/w3c/webdriver-bidi/issues/66" target="_blank" rel="noopener noreferrer" class=""><strong>HTTP Authentication</strong></a>: enables the ability to load a web page that is protected behind user credentials</li>
</ul>
<p>Note that even WebdriverIO will offer the latest WebDriver Bidi features, this doesn't mean that those are implemented and shipped in the browser. Every browser vendor has different priorities and resources available to get these new features added and while the teams make great progress it will take more time until everything specified in the protocol lands in a stable browser version. You can be ensured though that WebdriverIO will always provide a typed interface for you to use them once ready.</p>
<p>Furthermore I am working on a proposal to extend the WebdriverIO interface and include a <code>page</code> object next to the already known <code>browser</code>, <code>element</code> and <code>mock</code> objects to simplify accessing commands and events connected to a certain browsing context. For information about that soon!</p>
<p>I want to close up thanking the Mozilla and Google browser teams for their excellent collaboration and efforts to ship this new standard that will enable developers around the world ship high quality web applications in the future.</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Guide for Cross Platform E2E Test For Native Mobile APP]]></title>
        <id>https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app</id>
        <link href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app"/>
        <updated>2023-05-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This article is a must-read for those experiencing headaches with mobile automation testing in the context of Continuous Integration and Continuous Deployment (CICD), particularly when it involves native mobile Apps for Android and iOS. It’s quite challenging to find sufficient resources that cover this specific topic.]]></summary>
        <content type="html"><![CDATA[<p>This article is a must-read for those experiencing headaches with mobile automation testing in the context of Continuous Integration and Continuous Deployment (CICD), particularly when it involves native mobile Apps for Android and iOS. It’s quite challenging to find sufficient resources that cover this specific topic.</p>
<p><img decoding="async" loading="lazy" alt="Guide for Cross Platform E2E" src="https://webdriver.io/de/assets/images/ultimateGuide-7e1524ad6a3c73734c89bc26814c1c3f.png" width="1200" height="628" class="img_ahPx"></p>
<p>Within this article, I will guide you through a detailed step-by-step process on how to create a comprehensive end-to-end test pipeline at no cost, utilizing GitHub Actions for both the iOS and Android platforms. We will be using our beloved WebdriverIO framework throughout the tutorial.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="challenge">Challenge<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#challenge" class="hash-link" aria-label="Direkter Link zu Challenge" title="Direkter Link zu Challenge" translate="no">​</a></h2>
<p>Our challenge is to establish a unified pipeline workflow that enables testing of our native mobile application on both the iOS and Android platforms. In a <a href="https://medium.com/innovies-club/building-a-complete-e2e-pipeline-for-testing-native-mobile-apps-with-webdriverio-f2828753aa5d" target="_blank" rel="noopener noreferrer" class="">previous article</a>, we thoroughly explored the process of constructing a pipeline for testing an Android app using an emulator with GitHub Actions. To handle the E2E test for the Android component, we will reuse that workflow. However, we still need to address the remaining bigger challenge of creating a separate job for the iPhone/iPad simulator.</p>
<p>During my research, I came across an incredibly useful but often overlooked feature which is, the macOS GitHub runner comes <a href="https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md" target="_blank" rel="noopener noreferrer" class="">pre-equipped</a> with Xcode, the necessary SDKs for iPhone iOS simulators. This realization sparked an idea in my mind: why not replicate the process we followed for the Android emulator but this time for the iOS simulator? This is particularly exciting because GitHub Actions’ iOS runner supports virtualization, making it a viable option for our purposes.</p>
<p>This feature allows us to build our pipeline without any additional costs (up to a maximum of 2000 minutes).</p>
<p><img decoding="async" loading="lazy" alt="MacOS Runner" src="https://webdriver.io/de/assets/images/macos-runner-738b92e352fdad6213a4ce9cbd4d071e.png" width="1245" height="683" class="img_ahPx"></p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="workflow-structure">Workflow structure<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#workflow-structure" class="hash-link" aria-label="Direkter Link zu Workflow structure" title="Direkter Link zu Workflow structure" translate="no">​</a></h2>
<p>Our GitHub actions workflow will be basically the same as Android in the core concept but with a little technical variation</p>
<ul>
<li class="">Create simulator</li>
<li class="">Install dependencies</li>
<li class="">Execute the test</li>
<li class="">Generate the report</li>
</ul>
<p>Looks pretty straightforward, but how? Let’s see</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="step-1">Step 1<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#step-1" class="hash-link" aria-label="Direkter Link zu Step 1" title="Direkter Link zu Step 1" translate="no">​</a></h3>
<p>As previously mentioned, the GH Actions runner comes packed with a range of available simulators. While we could utilize one of these existing simulators, it would require using the deviceName and it's</p>
<p>randomly changing UUID for each execution. However, you can still extract the relevant UUID using shell commands.</p>
<p>To simplify the process and increase flexibility, we will create our own simulator. Since Xcode is already installed, we can make use of the “xcrun” CLI. To create a simulator from the installed iOS versions using the terminal, simply execute the following command:</p>
<div class="language-bash codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-bash codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl create "iPhone 14 Pro" "com.apple.CoreSimulator.SimDeviceType.iPhone-14-Pro" "com.apple.CoreSimulator.SimRuntime.iOS-16-0"</span><br></span></code></pre></div></div>
<p>Executing this command will result in the immediate creation of a simulator and the subsequent retrieval of its UUID.</p>
<p>To enhance re-usability and optimize the process, we can encapsulate this command within a shell script. With a few modifications, we can ensure that the UUID is stored as an environment variable in GitHub Runner which we will eventually use for our test capabilities.</p>
<div class="language-bash codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-bash codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Set iPhone model and iOS version</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">iphone_model="${IPHONE_MODEL// /-}"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ios_version="${IOS_VERSION//./-}"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">simulator_name="${iphone_model}"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">simulator_udid=$(xcrun simctl create "$IPHONE_MODEL" "com.apple.CoreSimulator.SimDeviceType.$iphone_model" "com.apple.CoreSimulator.SimRuntime.iOS-$ios_version")</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Export the simulator UDID as an environment variable</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export SIMULATOR_UDID="$simulator_udid"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "SIMULATOR_UDID=$SIMULATOR_UDID" &gt;&gt; $GITHUB_ENV</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Boot the simulator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xcrun simctl boot "$simulator_udid"</span><br></span></code></pre></div></div>
<p>By using the script above, we can provide the device model and iOS version as environment variables which can be stored in the environment sections in our workflow, this will create the simulator and store its UUID in GITHUB_ENV. This UUID will be essential for configuring the desired capabilities in our tests.</p>
<p><em>Since we are using IPHONE_MODEL and IOS_VERSION as environment variable in our shell script then we will have to set them in the environment section as shown below.</em></p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="step-2">Step 2<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#step-2" class="hash-link" aria-label="Direkter Link zu Step 2" title="Direkter Link zu Step 2" translate="no">​</a></h3>
<p>After successfully creating and booting up the simulator in the previous step, it’s crucial to verify that the process was completed without any issues and that the device is fully prepared for use.</p>
<p><img decoding="async" loading="lazy" alt="Checking booting status" src="https://webdriver.io/de/assets/images/bootingStatus-719fc7c233fc105e05c8739cb961411d.png" width="595" height="47" class="img_ahPx"></p>
<p>To ensure the successful starting of our test, it is crucial to confirm that the IOS has fully booted. For this purpose, I have created a code snippet that continuously monitors the device’s status until a specific output is obtained, signifying the completion of the simulator’s booting process.</p>
<div class="language-bash codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-bash codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">#!/bin/zsh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function wait_for_boot() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  printf "${G}==&gt; ${BL}Waiting for the simulator to boot...${NC}\n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  start_time=$(date +%s)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  spinner=( "⠹" "⠺" "⠼" "⠶" "⠦" "⠧" "⠇" "⠏" )</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  i=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  # Get the timeout value from the environment variable or use the default value of 60 seconds</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  timeout=${BOOT_TIMEOUT:-60}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  while true; do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    output=$(xcrun simctl bootstatus "$SIMULATOR_UDID")</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    echo "${output}"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if [[ $output == *"Device already booted, nothing to do."* ]]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "\e[K${G}==&gt; \u2713 Simulator booted successfully${NC}\n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      exit 0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    else</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "${YE}==&gt; Please wait ${spinner[$i]} ${NC}\r"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      i=$(( (i+1) % 8 ))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    elapsed_time=$(( $(date +%s) - $start_time ))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if [[ $elapsed_time -ge $timeout ]]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "${RED}==&gt; Timeout waiting for simulator to boot 🕛${NC}\n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      exit 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    sleep 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  done</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># Call the wait_for_boot function</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">wait_for_boot</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="step-3">Step 3<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#step-3" class="hash-link" aria-label="Direkter Link zu Step 3" title="Direkter Link zu Step 3" translate="no">​</a></h3>
<p>Proceeding further, we will cover the necessary steps and dependencies required for executing your tests. This includes the installation of Appium, the XCUITest driver, and the essential Node.js libraries.</p>
<div class="language-json codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-json codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"devDependencies"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/allure-reporter"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.10.4"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/appium-service"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.10.5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/cli"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.10.5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/local-runner"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^8.10.5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/mocha-framework"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"8.10.4"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"@wdio/spec-reporter"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"8.8.7"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"ts-node"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^10.9.1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"typescript"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^5.0.4"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"dependencies"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"allure-commandline"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"^2.22.1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"appium"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2.0.0-beta.71"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"appium-uiautomator2-driver"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"*"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"appium-xcuitest-driver"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"*"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="connecting-the-puzzle-pieces">Connecting the Puzzle Pieces<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#connecting-the-puzzle-pieces" class="hash-link" aria-label="Direkter Link zu Connecting the Puzzle Pieces" title="Direkter Link zu Connecting the Puzzle Pieces" translate="no">​</a></h2>
<p>Since now the key elements required to set up the environment for executing our mobile automation tests on the iOS simulator are ready, Let’s wrap them all into a single yaml file for GH actions</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Wdio</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">native</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">workflow_dispatch</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IPHONE_MODEL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> iPhone 8</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IOS_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">BOOT_TIMEOUT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">700</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">jobs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ios</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> macos</span><span class="token punctuation" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">13</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Export environment variables</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          export IPHONE_MODEL=$IPHONE_MODEL</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          export IOS_VERSION=$IOS_VERSION</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Start simulator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          chmod a+x ./sscript/start_simu.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          ./sscript/start_simu.sh</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Install dependencies</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          npm i</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Check simulator booting status</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          chmod a+x ./check_simu.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          ./check_simu.sh</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Execute the test</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          npm run ios</span><br></span></code></pre></div></div>
<p><em>Combine the simulator status check and simulator start into a single shell script would have been possible. However, I intentionally separated them to execute them individually. This allows me to utilize the time taken for the simulator to boot up and install the remaining dependencies. Afterwards, I can then proceed to check the status of the simulator. Similarly we will apply same approach to Android emulator (check previous article).</em></p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="build-cross-platform-workflow">Build cross-platform workflow<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#build-cross-platform-workflow" class="hash-link" aria-label="Direkter Link zu Build cross-platform workflow" title="Direkter Link zu Build cross-platform workflow" translate="no">​</a></h2>
<p>The time now to combine our Android workflow from the previous article without Ios workflow into one single workflow, using the matrix strategy as follows:</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Wdio</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">native</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">workflow_dispatch</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IPHONE_MODEL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> iPhone 8</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IOS_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">API_LEVEL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_NAME</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Nexus</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_DEVICE</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Nexus 5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">12</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_ARCH</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> x86_64</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_TARGET</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> google_apis</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_BUILD_TOOLS_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 34.0.0</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">rc4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_SDK_PACKAGES</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> system</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">images;android</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">32;google_apis;x86_64 platforms;android</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">32 build</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">tools;34.0.0</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">rc4 platform</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">tools emulator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_TIMEOUT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">350</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">BOOT_TIMEOUT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">700</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">jobs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ios</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> macos</span><span class="token punctuation" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">13</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">strategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">matrix</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">os</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">IOS</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">device</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$IPHONE_MODEL</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$IOS_VERSION</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Export environment variables</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          export IPHONE_MODEL=$IPHONE_MODEL</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          export IOS_VERSION=$IOS_VERSION</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># find the full workflow at the end of the article</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">android</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> macos</span><span class="token punctuation" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">13</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">strategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">matrix</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">os</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">Android</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">emulator_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$EMULATOR_NAME</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Add avdmanager and sdkmanager to system PATH</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          echo "$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/${{ env.ANDROID_BUILD_TOOLS_VERSION }}" &gt;&gt; $GITHUB_PATH</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Install Sdk</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          yes Y | sdkmanager --licenses</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          sdkmanager --install ${ANDROID_SDK_PACKAGES}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Build emulator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># find the full workflow at the end of the article</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># ...</span><br></span></code></pre></div></div>
<p>In the above example, we have integrated the IOS workflow mentioned earlier with the Android emulator workflow described in our previous <a href="https://medium.com/@Amr.sa/build-xplatform-native-mobile-automation-test-with-wdio-like-a-pro-4e8acc797ffe" target="_blank" rel="noopener noreferrer" class="">article</a>.</p>
<p><em>These are the recommended configurations that you may require for both the Android emulator and iPhone simulator. It’s important to note that the deviceName, platformVersion, and UUID are not hardcoded in our object. This flexibility allows us to easily switch between different versions and device models as needed.</em></p>
<div class="language-js codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-js codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> emulator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">platformName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'android'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string-property property" style="color:#36acaa">'appium:options'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">deviceName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">CI</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">EMULATOR_NAME</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Nexus'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">platformVersion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">CI</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">EMULATOR_VERSION</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'13'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">automationName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'uiautomator2'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appPackage</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'com.wdiodemoapp'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appWaitPackage</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'com.wdiodemoapp'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appActivity</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'com.wdiodemoapp.MainActivity'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appWaitActivity</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'com.wdiodemoapp.MainActivity'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">uiautomator2ServerLaunchTimeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">uiautomator2ServerInstallTimeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appWaitForLaunch</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">autoGrantPermissions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">adbExecTimeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">200000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">androidInstallTimeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">150000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">ignoreHiddenApiPolicyError</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">noReset</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">fullReset</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> simulator </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">platformName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'iOS'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string-property property" style="color:#36acaa">'appium:options'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">deviceName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">CI</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">IPHONE_MODEL</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Iphone-13'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">platformVersion</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">CI</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">IOS_VERSION</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'15.5'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">automationName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'XCUITest'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">bundleId</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'org.wdioNativeDemoApp'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">app</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'iOS-Simulator-NativeDemoApp-0.4.0.app.zip'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">udid</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">CI</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">env</span><span class="token punctuation" style="color:#393A34">.</span><span class="token constant" style="color:#36acaa">SIMULATOR_UDID</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'15A098DB-B8A0-4D6A-9057-23FF1F0F0D9B'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">useNewWDA</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">usePrebuiltWDA</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">wdaConnectionTimeout</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">180000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">appWaitForLaunch</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">noReset</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">fullReset</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">]</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="initial-execution">Initial Execution<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#initial-execution" class="hash-link" aria-label="Direkter Link zu Initial Execution" title="Direkter Link zu Initial Execution" translate="no">​</a></h2>
<p>The good news is that workflow is configured properly and the e2e test for the IOS app has been successfully executed</p>
<p><img decoding="async" loading="lazy" alt="Initial executions" src="https://webdriver.io/de/assets/images/initialExecution-ad9cc8b4ecb6c342f67ad44c26f1df1d.png" width="1036" height="687" class="img_ahPx"></p>
<p><img decoding="async" loading="lazy" alt="Initial executions" src="https://webdriver.io/de/assets/images/specReporter-4679071116a9783596a0c21ea4dc4881.png" width="797" height="298" class="img_ahPx"></p>
<p>Though the end-to-end test for the iPhone simulator has passed, it was observed that the test for the Android emulator shows instability.</p>
<p><img decoding="async" loading="lazy" alt="Initial executions" src="https://webdriver.io/de/assets/images/flakyJob-90a9032f0b5fde5f8deca0fde029cc72.png" width="502" height="333" class="img_ahPx"></p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="debugging">Debugging<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#debugging" class="hash-link" aria-label="Direkter Link zu Debugging" title="Direkter Link zu Debugging" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="system-ui-crush">System UI Crush<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#system-ui-crush" class="hash-link" aria-label="Direkter Link zu System UI Crush" title="Direkter Link zu System UI Crush" translate="no">​</a></h3>
<p>It appears that running Android for the first time in headless mode occasionally results in random system UI unresponsive issues. Unfortunately, this issue is preventing us from executing the tests as the UI system is unresponsive which consequently disrupts Appium from proper interaction with the app.</p>
<p>The issue was confirmed when reviewing the allure report screenshots</p>
<p><img decoding="async" loading="lazy" alt="Allure Report" src="https://webdriver.io/de/assets/images/systemUi-60858fce6b7ce906b3522db5f9415010.png" width="898" height="852" class="img_ahPx"></p>
<p>This explains why the terminal log displayed that Appium was unable to locate any element, despite the successful launch of the app.</p>
<p><img decoding="async" loading="lazy" alt="Test Run Log" src="https://webdriver.io/de/assets/images/unableToFind-b5829953c2312a11f5ffb8fc02877e72.png" width="1505" height="1172" class="img_ahPx"></p>
<p>This makes sense as Appium is trying to find the desired element but on the current running activity which is <code>.systemui</code>, even though our target app is launched in the background</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="connection-timeout">Connection timeout<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#connection-timeout" class="hash-link" aria-label="Direkter Link zu Connection timeout" title="Direkter Link zu Connection timeout" translate="no">​</a></h3>
<p>It has been noted that on certain occasions, Appium encountered failures in initiating the test, with all connection retry attempts proving unsuccessful. However, after conducting a thorough investigation, it was discovered that the installation of the Apk file to the Android emulator through the app:“./test.apk” capability was taking an unusually long time, requiring a significantly extended connection timeout to ensure successful installation which is not the best solution.</p>
<p>Now that we have identified the issue and its root cause, it’s time to address and resolve them.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="resolving">Resolving<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#resolving" class="hash-link" aria-label="Direkter Link zu Resolving" title="Direkter Link zu Resolving" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="system-ui-crush-1">System UI Crush<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#system-ui-crush-1" class="hash-link" aria-label="Direkter Link zu System UI Crush" title="Direkter Link zu System UI Crush" translate="no">​</a></h3>
<p>Fortunately, we can utilize the advantage of being able to grep the current running activity on an Android device. This privilege allows us to detect whether the system UI or any similar Android service will crash or function normally. We can achieve this by executing the following adb shell command:</p>
<div class="language-shell codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-shell codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">adb shell dumpsys window 2&gt;/dev/null | grep -i mCurrentFocus</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="Android Failure" src="https://webdriver.io/de/assets/images/androidFailure1-65695d5ed92ff788abcb40e7681508d5.png" width="684" height="139" class="img_ahPx"></p>
<p><img decoding="async" loading="lazy" alt="Android Failure" src="https://webdriver.io/de/assets/images/androidFailure2-46886d79e554bcc1d97e7e4980fe60f0.png" width="771" height="112" class="img_ahPx"></p>
<p>In our ongoing implementation, we can mimic our natural behavior when encountering this issue on an Android device. Specifically, we will continuously click the home button until the issue is resolved. Once the problem is resolved and the Android system is functioning correctly, we anticipate observing the “.NexusLauncherActivity” as the current main activity running (where “Nexus” represents the Android device).</p>
<p>In order to achieve this, I have developed the following shell script:</p>
<div class="language-bash codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-bash codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">#!/bin/bash</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function check_current_focus() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  printf "==&gt; Checking emulator running activity \n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  start_time=$(date +%s)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  i=0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  timeout=20</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  target="com.google.android.apps.nexuslauncher.NexusLauncherActivity"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  while true; do</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    result=$(adb shell dumpsys window 2&gt;/dev/null | grep -i mCurrentFocus)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if [[ $result == *"$target"* ]]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "==&gt;  Activity is okay: \n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "$result\n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      break</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    else</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      adb shell input keyevent KEYCODE_HOME</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "==&gt; Menu button is pressed \n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      i=$(( (i+1) % 8 ))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    current_time=$(date +%s)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    elapsed_time=$((current_time - start_time))</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    if [ $elapsed_time -gt $timeout ]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      printf "==&gt; Timeout after ${timeout} seconds elapsed 🕛.. \n"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      return 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    sleep 4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  done</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">check_current_focus</span><br></span></code></pre></div></div>
<p>The shown function above will continuously loop, If the main activity is not found (NexusLauncherActivity), it will send a home button event and repeat the process until its found or timeout is reached.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="connection-timeout-1">Connection timeout<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#connection-timeout-1" class="hash-link" aria-label="Direkter Link zu Connection timeout" title="Direkter Link zu Connection timeout" translate="no">​</a></h3>
<p>Rather than significantly extending the Appium connection timeout, I will handle the APK installation in a separate step along with the main activity checking.</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Install APK</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          adb install Android-NativeDemoApp-0.4.0.apk</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          chmod a+x ./mainActivityCheck.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          ./mainActivityCheck.sh</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="Testing Apk installation and the shell script" src="https://webdriver.io/de/assets/images/handleUiFailure-b27edd10f5488756541124cc9897cccd.png" width="1034" height="231" class="img_ahPx"></p>
<p>Excellent! Our solution has been executed successfully with the proper installation of the APK. As expected, the system UI was not responsive, and the shell script effectively managed and handled the situation.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="optimizing-and-enhancing-workflow">Optimizing and Enhancing workflow<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#optimizing-and-enhancing-workflow" class="hash-link" aria-label="Direkter Link zu Optimizing and Enhancing workflow" title="Direkter Link zu Optimizing and Enhancing workflow" translate="no">​</a></h2>
<p>I have improved the workflow dispatch to provide better control over the platforms on which I can execute my tests, whether it be iOS, Android, or cross-platform.</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Wdio</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">native</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">workflow_dispatch</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">inputs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">e2e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> choice</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Select a platform</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">required</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">options</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> xplatform</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ios</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> android</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xplatform</span><br></span></code></pre></div></div>
<p>Consequently, our jobs should be adjusted</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Wdio</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">native</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">workflow_dispatch</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">inputs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">e2e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> choice</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Select a platform</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">required</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">options</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> xplatform</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ios</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> android</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">default</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> xplatform</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">permissions</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">contents</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">pages</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">id-token</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> write</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IPHONE_MODEL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> iPhone 8</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">IOS_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16.2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">API_LEVEL</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_NAME</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Nexus</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_DEVICE</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Nexus 5</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">12</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_ARCH</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> x86_64</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_TARGET</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> google_apis</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_BUILD_TOOLS_VERSION</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> 34.0.0</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">rc4</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ANDROID_SDK_PACKAGES</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> system</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">images;android</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">32;google_apis;x86_64 platforms;android</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">32 build</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">tools;34.0.0</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">rc4 platform</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">tools emulator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">EMULATOR_TIMEOUT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">350</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">BOOT_TIMEOUT</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">700</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">jobs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">ios</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> macos</span><span class="token punctuation" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">13</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> contains(github.event.inputs.e2e</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> 'ios') </span><span class="token punctuation" style="color:#393A34">|</span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"> contains(github.event.inputs.e2e</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> 'xplatform') </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">strategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">matrix</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">os</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">IOS</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">device</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$IPHONE_MODEL</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$IOS_VERSION</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># find the full workflow at the end of the article</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">android</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> macos</span><span class="token punctuation" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">13</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> contains(github.event.inputs.e2e</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> 'android') </span><span class="token punctuation" style="color:#393A34">|</span><span class="token punctuation" style="color:#393A34">|</span><span class="token plain"> contains(github.event.inputs.e2e</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> 'xplatform') </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">strategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">matrix</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">os</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">Android</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">emulator_name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">$EMULATOR_NAME</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># find the full workflow at the end of the article</span><br></span></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="Input Dispatch" src="https://webdriver.io/de/assets/images/dispatch-e7c89518515016d372c5868aa75e2802.png" width="401" height="425" class="img_ahPx"></p>
<p>Finally, Generate our report and deploy it to the GitHub page out of the box</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Generate report</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> always()</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></span><span class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">          npx allure generate report/allure-results</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Setup Pages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> always()</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/configure</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Upload artifact</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> always()</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/upload</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">artifact@v1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">with</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./allure-report'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deploy to GitHub Pages</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">if</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> always()</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> deployment</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/deploy</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pages@v2</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="workflow-execution">Workflow Execution<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#workflow-execution" class="hash-link" aria-label="Direkter Link zu Workflow Execution" title="Direkter Link zu Workflow Execution" translate="no">​</a></h2>
<p><img decoding="async" loading="lazy" alt="Workflow execution" src="https://webdriver.io/de/assets/images/workflowexec-deb8bb115444858d0d85b6583b4995bf.png" width="991" height="842" class="img_ahPx"></p>
<p><img decoding="async" loading="lazy" alt="iOS Job" src="https://webdriver.io/de/assets/images/iosJob-77e99705a8fd3f6922bf308b8dad6dc1.png" width="1134" height="1327" class="img_ahPx">
<img decoding="async" loading="lazy" alt="Android Job" src="https://webdriver.io/de/assets/images/androidJob-2dbeac2cd654a0af5d54c86331054a67.png" width="1134" height="1327" class="img_ahPx"></p>
<p><img decoding="async" loading="lazy" alt="Allure report" src="https://webdriver.io/de/assets/images/success-876379c7099312cb290d76fd9bb307de.png" width="928" height="885" class="img_ahPx"></p>
<p>Fantastic news! Our workflow is now functioning flawlessly and exhibits complete stability. The workflow can be triggered against a single platform, such as Android or iOS, or simultaneously against both platforms in parallel.</p>
<div class="docusaurus-theme-github-codeblock"><div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">Full workflow</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">loading</span><span class="token punctuation" style="color:#393A34">...</span><br></span></code></pre></div></div><div style="font-size:.9em;font-weight:600;color:#0E75DD;text-align:right;padding-bottom:13px;text-decoration:underline"><a href="https://github.com/amrsa1/wdio-xplatform-mobile-app/blob/main/.github/workflows/xplatform_workflow.yml#L1-L178" class="githubLink" style="margin:0 10px" target="_blank">View on GitHub</a></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="conclusion">Conclusion<a href="https://webdriver.io/de/blog/2023/05/31/guied-for-xplatform-nativeMobile-app#conclusion" class="hash-link" aria-label="Direkter Link zu Conclusion" title="Direkter Link zu Conclusion" translate="no">​</a></h2>
<p>By leveraging the capabilities provided by GitHub Actions, which offer out-of-the-box SDKs for both Android and iOS, we gain a significant advantage. This allows us to construct an efficient end-to-end test pipeline without incurring any costs or relying on mobile device farm cloud services. Although conducting tests on real devices is preferable, particularly for Android, the cost-free nature of this approach presents a satisfactory compromise.</p>
<p>Throughout our discussion, we have provided a step-by-step demonstration of building a cross-platform end-to-end test using the GitHub Actions pipeline for native mobile Apps. We have addressed various challenges, obstacles, and issues, ensuring a thorough understanding of the process. Armed with this knowledge, you should find it easier to construct your own customized pipeline that caters to your specific requirements.</p>]]></content>
        <author>
            <name>Amr Salem</name>
            <uri>https://www.linkedin.com/in/amrsalem1/</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Our Approach to Interactive and Tested Documentation]]></title>
        <id>https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation</id>
        <link href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation"/>
        <updated>2023-02-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The WebdriverIO framework is a versatile tool that offers a lot of features for you to play around with. The goal of our project documentation is to communicate these features well and give you an understanding, on how they could be applied in your project. A central contributor to this are code examples. Many times they can convey the principle idea of a feature like a picture that is worth a thousand words.]]></summary>
        <content type="html"><![CDATA[<p>The WebdriverIO framework is a versatile tool that offers a lot of features for you to play around with. The goal of our <a href="https://webdriver.io/" target="_blank" rel="noopener noreferrer" class="">project documentation</a> is to communicate these features well and give you an understanding, on how they could be applied in your project. A central contributor to this are code examples. Many times they can convey the principle idea of a feature like a picture that is worth a thousand words.</p>
<p>It is not a surprise that many projects out there have code examples embedded in their project documentation. Many of them are even interactive and allow users to fiddle around with the code in real time, e.g. the <a href="https://beta.reactjs.org/learn/adding-interactivity" target="_blank" rel="noopener noreferrer" class="">new React Docs</a>, or provide "playgrounds" with live examples, like on <a href="https://svelte.dev/examples/hello-world" target="_blank" rel="noopener noreferrer" class="">svelte.dev</a>.</p>
<p><img decoding="async" loading="lazy" alt="Live Examples on the new React docs" src="https://webdriver.io/de/assets/images/react-live-962facb8e24f7c1d916797df7441cec3.gif" width="966" height="492" class="img_ahPx">
</p><center><em>Live Examples on the <a href="https://beta.reactjs.org/learn/adding-interactivity" target="_blank">new React docs</a></em></center><p></p>
<br>
<p>When it comes to having code examples on a documentation page, a common problem that arises with them is that examples:</p>
<ul>
<li class="">are made up and often don't reflect reality</li>
<li class="">contain errors because we are all just humans</li>
<li class="">are getting outdated as interfaces change</li>
<li class="">can be difficult to apply in your own project</li>
</ul>
<p>As an attempt to improve our code examples on this project page we started to roll out some changes to the documentation that hopefully addresses these issues:</p>
<div class="docusaurus-theme-github-codeblock"><div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">queryElements/singleElements.js</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">loading</span><span class="token operator" style="color:#393A34">...</span><br></span></code></pre></div></div><div style="font-size:.9em;font-weight:600;color:#0E75DD;text-align:right;padding-bottom:13px;text-decoration:underline"><a href="https://github.com/webdriverio/example-recipes/blob/main/queryElements/singleElements.js#L9-L10" class="githubLink" style="margin:0 10px" target="_blank">View on GitHub</a></div></div>
<p>As you can see, some examples now have two buttons that allow you to run them or view them on GitHub. But what does that mean?</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="extract-examples-from-docs">Extract Examples from Docs<a href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation#extract-examples-from-docs" class="hash-link" aria-label="Direkter Link zu Extract Examples from Docs" title="Direkter Link zu Extract Examples from Docs" translate="no">​</a></h2>
<p>As a first step we started to remove all code examples from our documentation page and moved them into a <a href="https://github.com/webdriverio/example-recipes" target="_blank" rel="noopener noreferrer" class="">dedicated repository</a>. This allows us to treat these examples as code and set-up the necessary infrastructure, e.g. CI/CD or automated dependency updates, to ensure quality and correctness.</p>
<p>So say hello 👋 to this new repository in our organization that now contains a lot of examples that we re-use on this website.</p>
<p><img decoding="async" loading="lazy" src="https://opengraph.githubassets.com/b9f11016590a96e4846d047aa81077a62d81c8d38ed769e4ff4ca6638f8e13e4/webdriverio/example-recipes" alt="&quot;webdriverio/example-recipes&quot; repository" class="img_ahPx">
</p><center><em><a href="https://github.com/webdriverio/example-recipes" target="_blank">webdriverio/example-recipes</a></em></center><p></p>
<br>
<p>You can see that every example is self contained in its own directory to keep everything very simple. A big list of <a href="https://github.com/webdriverio/example-recipes/blob/a49fdf935b689aafc22219ea534e119796cb9f07/package.json#L24-L59" target="_blank" rel="noopener noreferrer" class="">NPM scripts</a> allows you to run specific examples with just a single command.</p>
<p>In order to embed the examples back into the website, we are using a <a href="https://github.com/christian-bromann/docusaurus-theme-github-codeblock" target="_blank" rel="noopener noreferrer" class="">plugin for Docusaurus</a> that downloads the code based on a simple GitHub reference link. So instead of having code within our markdown files, we just reference the location on Github, e.g.:</p>
<div class="docusaurus-theme-github-codeblock"><div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">setup/testrunner.js</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">loading</span><span class="token operator" style="color:#393A34">...</span><br></span></code></pre></div></div><div style="font-size:.9em;font-weight:600;color:#0E75DD;text-align:right;padding-bottom:13px;text-decoration:underline"><a href="https://github.com/webdriverio/example-recipes/blob/main/setup/testrunner.js#L5-L8" class="githubLink" style="margin:0 10px" target="_blank">View on GitHub</a></div></div>
<p>The plugin then downloads the code and only shows provided code lines of that file. Here is the final result of that:</p>
<div class="docusaurus-theme-github-codeblock"><div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">setup/testrunner.js</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">loading</span><span class="token operator" style="color:#393A34">...</span><br></span></code></pre></div></div><div style="font-size:.9em;font-weight:600;color:#0E75DD;text-align:right;padding-bottom:13px;text-decoration:underline"><a href="https://github.com/webdriverio/example-recipes/blob/main/setup/testrunner.js#L5-L8" class="githubLink" style="margin:0 10px" target="_blank">View on GitHub</a></div></div>
<p>If you are using a different tool for building your static docs, chances are that it has similar plugins available to just do that.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="testing-examples">Testing Examples<a href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation#testing-examples" class="hash-link" aria-label="Direkter Link zu Testing Examples" title="Direkter Link zu Testing Examples" translate="no">​</a></h2>
<p>Now that we have everything nicely encapsulated into a dedicated repository, we can use CI/CD to test all examples on regular basis. A simple <a href="https://github.com/webdriverio/example-recipes/blob/main/.github/workflows/test.yml" target="_blank" rel="noopener noreferrer" class="">GitHub workflow</a> can trigger the execution of these examples and have the pipeline fail if any of them have an error:</p>
<div class="language-yaml codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-yaml codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Test</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">push</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pull_request</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">jobs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">test</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">runs-on</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">strategy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">matrix</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">exampleDir</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> click</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token comment" style="color:#999988;font-style:italic"># more example directories here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token comment" style="color:#999988;font-style:italic"># ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> api/webdriver</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">steps</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Checkout</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/checkout@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">uses</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> actions/setup</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">node@v3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">with</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">node-version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">18</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Install</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> npm install</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Test</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">run</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> npm run $</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> matrix.exampleDir </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">working-directory</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> matrix.exampleDir </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>Most of the examples are written as normal WebdriverIO test files and contain normal assertions like any other test would do, e.g. an example that shows how to fetch elements using command chaining would be written as following:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">it</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'should get the text of a menu link'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> menu$ </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#menu'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// or `browser.$('#menu')`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> menu$</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'li'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'a'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// outputs: "API"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">menu$</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'li'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'a'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toHaveText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'API'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>With the ability to reference certain code lines we can just strip out the testing part of the example and focus on what's important:</p>
<div class="docusaurus-theme-github-codeblock"><div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">queryElements/singleElements.js</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">loading</span><span class="token operator" style="color:#393A34">...</span><br></span></code></pre></div></div><div style="font-size:.9em;font-weight:600;color:#0E75DD;text-align:right;padding-bottom:13px;text-decoration:underline"><a href="https://github.com/webdriverio/example-recipes/blob/main/queryElements/singleElements.js#L9-L10" class="githubLink" style="margin:0 10px" target="_blank">View on GitHub</a></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="keep-examples-up-to-date">Keep Examples up to Date<a href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation#keep-examples-up-to-date" class="hash-link" aria-label="Direkter Link zu Keep Examples up to Date" title="Direkter Link zu Keep Examples up to Date" translate="no">​</a></h2>
<p>Another advantage of having a CI/CD infrastructure is the ability to use workflows that ensure everything stays up to date. Since WebdriverIO code is hosted on GitHub, we setup Dependabot to <a href="https://github.com/webdriverio/example-recipes/blob/main/.github/dependabot.yml" target="_blank" rel="noopener noreferrer" class="">update all dependencies</a> on weekly basis. An additional <a href="https://github.com/webdriverio/example-recipes/blob/main/.github/workflows/update.yml" target="_blank" rel="noopener noreferrer" class="">GitHub workflow</a> helps us to auto-merge these dependency updates so that we only need to deal with them in case they cause issues due to failing tests.</p>
<p>This process is very important and helps us to ensure that changes in WebdriverIO don't break any of our examples we use in our documentation. It is also a great additional feedback loop and creates more confidence when a new version is released that did not break any of our examples.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="make-examples-easy-accessible">Make Examples Easy Accessible<a href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation#make-examples-easy-accessible" class="hash-link" aria-label="Direkter Link zu Make Examples Easy Accessible" title="Direkter Link zu Make Examples Easy Accessible" translate="no">​</a></h2>
<p>Lastly, to make every example very easy to access and run, we are using a feature of a very cool VS Code Extension called <a href="https://runme.dev/" target="_blank" rel="noopener noreferrer" class="">Runme</a> that helps to check out code locally with a simple click on a button. If you haven't installed Runme yet, go check it out on the <a href="https://marketplace.visualstudio.com/items?itemName=stateful.runme" target="_blank" rel="noopener noreferrer" class="">VS Code Marketplace</a> or find it in your VS Code:</p>
<p><img decoding="async" loading="lazy" alt="Runme on the VS Code Marketplace" src="https://webdriver.io/de/assets/images/runme-marketplace-42249b0ed54b3e377bd692d5b4e0ce11.png" width="1545" height="443" class="img_ahPx">
</p><center><em>Runme on the <a href="https://marketplace.visualstudio.com/items?itemName=stateful.runme" target="_blank">VS Code Marketplace</a></em></center><p></p>
<br>
<p>Many surveys have shown that VS Code is the dominant IDE for many developers around the world. With the <code>Run Example</code> button we allow all these users to access the repository with a single click. The button is a simple link with a custom <code>vscode://</code> protocol that will prompt you for permission to open it in VS Code. There, the extension will pick up the link information containing which repository it needs to check out and which markdown file to open. If the extension is not installed, it will automatically do that for you, if you consent.</p>
<p><img decoding="async" loading="lazy" alt="Run Example with Runme" src="https://webdriver.io/de/assets/images/wdio-demo-blog-b1a5461eb1567d36c5bdd111e0a66105.gif" width="1168" height="898" class="img_ahPx">
</p><center><em>Run Example with <a href="https://runme.dev/" target="_blank">Runme</a></em></center><p></p>
<br>
<p>Once the repository is checked out, Runme will open a dedicated <code>README.md</code> for the example in an interactive notebook experience. It will explain the example and walks you through it. It allows to execute the code cells within the VS Code terminal securely so that setting up and running the example is done with a simple click and requires no additional application to be opened.</p>
<p>For folks that don't have VS Code installed can still access the repository, check it out manually and run the examples as well.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="get-involved">Get Involved<a href="https://webdriver.io/de/blog/2023/02/28/interactive-and-tested-documentation#get-involved" class="hash-link" aria-label="Direkter Link zu Get Involved" title="Direkter Link zu Get Involved" translate="no">​</a></h2>
<p>WebdriverIO has many examples and a lot of commands and APIs to document. This is a great opportunity for you to get involved and contribute to the project by:</p>
<ul>
<li class="">adding more examples to <a href="https://github.com/webdriverio/example-recipes" target="_blank" rel="noopener noreferrer" class=""><code>webdriverio/example-recipes</code></a> or</li>
<li class="">reference existing examples in our documentation</li>
</ul>
<p>Feel free to also raise <a href="https://github.com/webdriverio/webdriverio/issues/new/choose" target="_blank" rel="noopener noreferrer" class="">an issue</a> if you have any questions or feedback.</p>
<p>I think this is a very cool way to provide an interactive and simple way to provide code examples for a framework that requires a specific environment that is not a browser, e.g. Node.js. If you are a framework author and run your docs with Docusaurus, feel free to copy this approach if you like it. It's Open Source and free.</p>
<p>Thanks for reading!</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[WebdriverIO v8 Released]]></title>
        <id>https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released</id>
        <link href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released"/>
        <updated>2022-12-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[While it took a bit longer than expected the WebdriverIO team is excited to announce that we finally released v8 today! 🎉 🎉 🎉]]></summary>
        <content type="html"><![CDATA[<p>While it took a bit longer than expected the WebdriverIO team is excited to announce that we finally released <code>v8</code> today! 🎉 🎉 🎉</p>
<p>As with almost all of the last major updates we again had to touch every single file of the project. This time our major goal for the new version was to finally transition from CommonJS to ESM which enables us to continue with important dependency updates and avoid security issues. Furthermore, we cleaned up some technical debt, e.g. removed all code related to synchronous command execution which was <a href="https://webdriver.io/blog/2021/07/28/sync-api-deprecation" target="_blank" rel="noopener noreferrer" class="">deprecated</a> last year, as well as implemented a new Action API interface and streamlined the way WebdriverIO deals with global objects using the test runner.</p>
<p>In this blog post, we go through every important change and explain what you need to do to upgrade to <code>v8</code>. Spoiler alert: in most cases no updates to your tests are necessary 😉</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="drop-nodejs-v12-v13-and-v14-support">Drop Node.js v12, v13 and v14 Support<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#drop-nodejs-v12-v13-and-v14-support" class="hash-link" aria-label="Direkter Link zu Drop Node.js v12, v13 and v14 Support" title="Direkter Link zu Drop Node.js v12, v13 and v14 Support" translate="no">​</a></h2>
<p>We've dropped support for Node v12 and v14, latter was moved into a maintenance LTS phase by the Node.js team in October 2021. While it is technically fine to continue using Node.js v14, we don't see a reason why you shouldn't update to Node.js v16 or ideally v18 directly.</p>
<p>To update Node.js, it is important to know how it was installed in the first place. If you are in a Docker environment, you can just upgrade the base image like:</p>
<div class="language-git codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-git codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">- FROM mhart/alpine-node:14</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">+ FROM mhart/alpine-node:18</span><br></span></code></pre></div></div>
<p>We recommend using <a href="https://github.com/nvm-sh/nvm" target="_blank" rel="noopener noreferrer" class="">NVM</a> (Node Version Manager) to install and manage Node.js versions. You can find a detailed description of how to install NVM and update Node in their <a href="https://github.com/nvm-sh/nvm#installing-and-updating" target="_blank" rel="noopener noreferrer" class="">project readme</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="commonjs-to-esm-transition">CommonJS to ESM Transition<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#commonjs-to-esm-transition" class="hash-link" aria-label="Direkter Link zu CommonJS to ESM Transition" title="Direkter Link zu CommonJS to ESM Transition" translate="no">​</a></h2>
<p>The transition to the new module system has been the biggest chunk of work related to this release. It required us to update all module imports, transitioning from <a href="https://jestjs.io/" target="_blank" rel="noopener noreferrer" class="">Jest</a> to <a href="https://vitest.dev/" target="_blank" rel="noopener noreferrer" class="">Vitest</a> as a unit test framework and rewrite various parts within the code base. While this affected every single file it "should" be unrecognizable to you. If your project still uses CommonJS, WebdriverIO will work just fine as both module systems continue to be supported. This is also the case when using <code>webdriver</code>, <code>devtools</code> or <code>webdriverio</code> as a <a class="" href="https://webdriver.io/de/docs/api/modules">module</a>.</p>
<p>If you have been using Babel only to use <code>import</code> statements in your tests, you can remove the integration as this is now supported by ESM natively. If you like to continue using CommonJS and <code>require</code>, that is fine too, no changes are needed to update to <code>v8</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="a-new-runner-for-unit-and-component-testing-in-the-browser">A new Runner for Unit and Component Testing in the Browser<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#a-new-runner-for-unit-and-component-testing-in-the-browser" class="hash-link" aria-label="Direkter Link zu A new Runner for Unit and Component Testing in the Browser" title="Direkter Link zu A new Runner for Unit and Component Testing in the Browser" translate="no">​</a></h2>
<p>If it comes to one feature we are really excited about in this release it is the new browser runner 🙌 I've been writing and testing a lot of web components in this past year and was always frustrated about the fact that they would be tested against <a href="https://www.npmjs.com/package/jsdom" target="_blank" rel="noopener noreferrer" class="">JSDOM</a> rather than an actual browser. JSDOM is a re-implementation of many Web APIs in Node.js and is a great tool for simple testing but it doesn't replace an actual DOM implementation within a browser. Especially using JSDOM for component testing has <a class="" href="https://webdriver.io/de/docs/runner#browser-runner">various disadvantages</a> compared to running tests in the browser.</p>
<p>Furthermore running component tests through WebdriverIO allows to use the WebdriverIO <a class="" href="https://webdriver.io/de/docs/api">API</a> seamlessly and enables real user interaction with your components through the <a href="https://w3c.github.io/webdriver/" target="_blank" rel="noopener noreferrer" class="">WebDriver protocol</a>. This makes those interactions more realistic compared to emitting them through JavaScript. It comes also with 1st class support for popular utility frameworks such as <a href="https://testing-library.com/" target="_blank" rel="noopener noreferrer" class="">Testing Library</a> and allows to use both APIs interchangeably. Check out how you can use Testing Library for rendering and fetching elements while using WebdriverIO for interacting with the component:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_fSo6">vue.test.ts</div><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> expect </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@wdio/globals'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> render </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@testing-library/vue'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> Component </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'./components/Component.vue'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">describe</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Vue Component Testing'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">it</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'increments value on click'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// The render method returns a collection of utilities to query your component.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> getByText </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">Component</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// getByText returns the first matching node for the provided text, and</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// throws an error if no elements match or if more than one match is found.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">getByText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Times clicked: 0'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> button </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">getByText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'increment'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Dispatch a native click event to our button element.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> button</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> button</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token function" style="color:#d73a49">getByText</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Times clicked: 2'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// assert with Testing Library</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">expect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'p=Times clicked: 2'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">toExist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// assert with WebdriverIO</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>The new browser runner allows you to load and execute tests within the browser rather than in Node.js. This allows you to access all Web APIs to render web components or to run unit tests for your frontend modules. Under the hood it uses <a href="https://vitejs.dev/" target="_blank" rel="noopener noreferrer" class="">Vite</a> to load all dependencies and make the integration seamless.</p>
<p>If you have been using <a href="https://github.com/karma-runner/karma" target="_blank" rel="noopener noreferrer" class="">Karma</a> for running unit tests in the browser you can switch over to WebdriverIO which provides the same capabilities but offers better support and integration to other services and reporters. It also seems that the Karma project is not much maintained these days and has <a href="https://github.com/karma-runner/karma/issues/3823" target="_blank" rel="noopener noreferrer" class="">unresovled security vulnerabilities</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="new-action-interface">New Action Interface<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#new-action-interface" class="hash-link" aria-label="Direkter Link zu New Action Interface" title="Direkter Link zu New Action Interface" translate="no">​</a></h2>
<p>For many years users that liked to run more complex interactions on their applications using WebDriver's <a href="https://w3c.github.io/webdriver/#actions" target="_blank" rel="noopener noreferrer" class="">actions API</a> had to know many details about the command to construct the correct payload. With <code>v8</code> of WebdriverIO, we now ship a new interface that makes executing various actions much easier.</p>
<p>With two new browser commands: <code>action</code> and <code>actions</code>, it is now much simpler and type-safe to run the right action, e.g. sending key events to the browser:</p>
<div class="language-js codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-js codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">action</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'key'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">down</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'f'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">up</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'f'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">down</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'o'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">up</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'o'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">down</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'o'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">up</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'o'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">perform</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Read more on the new action interface in the <a class="" href="https://webdriver.io/de/docs/api/browser/action">WebdriverIO API</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="webdriver-bidi-support">WebDriver BiDi Support<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#webdriver-bidi-support" class="hash-link" aria-label="Direkter Link zu WebDriver BiDi Support" title="Direkter Link zu WebDriver BiDi Support" translate="no">​</a></h2>
<p>A strong argument to use WebdriverIO as opposed to other tools is the fact that it is based on the <a href="https://w3c.github.io/webdriver/" target="_blank" rel="noopener noreferrer" class="">WebDriver protocol</a>, which is a web standard for automating browsers. It guarantees the ability to run tests in browsers that are used by your users as opposed to a browser engine, which can be very different from a feature and security aspect. The <a href="https://www.w3.org/groups/wg/browser-tools-testing" target="_blank" rel="noopener noreferrer" class="">W3C Working Group</a> has been working on <a href="https://w3c.github.io/webdriver-bidi/" target="_blank" rel="noopener noreferrer" class="">a new version</a> of the protocol that will enable better introspection capabilities and new automation primitives.</p>
<p>With this release, users can start accessing these new protocol features as they become available in browsers. Over time more commands will transition to the new protocol under the hood while the interface remains the same. We are all very excited about the new capabilities and opportunities this protocol will provide, e.g. listening to log events while running tests, e.g.:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">send</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    method</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'session.subscribe'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    params</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> events</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'log.entryAdded'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * returns:</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *    "method":"log.entryAdded",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *    "params":</span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "type":"console",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "method":"log",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "realm":null,</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "args":[</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *          </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">{</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *             "type":"string",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *             "value":"Hello Bidi"</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *          </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       ],</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "level":"info",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "text":"Hello Bidi",</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *       "timestamp":1657282076037</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> *    </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * </span><span class="token doc-comment comment punctuation" style="color:#393A34;font-style:italic">}</span><span class="token doc-comment comment" style="color:#999988;font-style:italic"></span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'message'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'received %s'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token doc-comment comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> * trigger listener</span><br></span><span class="token-line" style="color:#393A34"><span class="token doc-comment comment" style="color:#999988;font-style:italic"> */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token builtin">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello Bidi"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>We are following and supporting the development of all browser vendors to ensure new features are working as expected and can be used through a lean user interface. For more information on this topic check out my talk on <a href="https://www.youtube.com/watch?v=z9v5v1MZ2Y0" target="_blank" rel="noopener noreferrer" class="">The Evolution of Browser Automation</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="optional-globals">Optional Globals<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#optional-globals" class="hash-link" aria-label="Direkter Link zu Optional Globals" title="Direkter Link zu Optional Globals" translate="no">​</a></h2>
<p>When using the WebdriverIO test runner it would usually register the <code>browser</code> object or the <code>$</code> and <code>$$</code> command to the global scope as these are usually often used when writing tests. However, attaching objects to the global scope is not seen as best practice and can cause side effects when other modules decide to do the same. Therefore with <code>v8</code>, it is now up to the user whether they like to continue attaching these objects and methods to the global scope or prefer importing them directly, via:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> browser</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> $</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> $$</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> expect </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@wdio/globals'</span><br></span></code></pre></div></div>
<p>A new configuration property called <a href="https://v8.webdriver.io/docs/options#injectglobals" target="_blank" rel="noopener noreferrer" class=""><code>injectGlobals</code></a> (defaults: <code>true</code>) handles whether the test runner modifies the global scope or not. If your setup works fine using global objects, no change is needed to update to <code>v8</code>. However, we recommend importing WebdriverIO-related interfaces directly to ensure no side effects can happen.</p>
<p><strong>Note:</strong> If you are using TypeScript, updates to the <code>tsconfig.json</code> are necessary to reflect changes made to the location of the WebdriverIO types. These are now part of the <code>@wdio/globals</code> package:</p>
<div class="language-git codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-git codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">{</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    "compilerOptions": {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        "types": [</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            "node",</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-           "webdriverio/async"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">+           "@wdio/globals/types"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="miscellaneous">Miscellaneous<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#miscellaneous" class="hash-link" aria-label="Direkter Link zu Miscellaneous" title="Direkter Link zu Miscellaneous" translate="no">​</a></h2>
<p>Aside from these major updates, the team has spent time improving the documentation and introduced new API docs around WebdriverIO objects like <a class="" href="https://webdriver.io/de/docs/api/browser"><code>browser</code></a>, <a class="" href="https://webdriver.io/de/docs/api/element"><code>element</code></a> and <a class="" href="https://webdriver.io/de/docs/api/mock"><code>mock</code></a>. Furthermore, we removed the <code>config</code> property from the <code>browser</code> object. If you have been using it to access data from the WDIO config, we suggest replacing it with <code>options</code>, e.g.:</p>
<div class="language-git codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-git codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">- browser.config.hostname</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">+ browser.options.hostname</span><br></span></code></pre></div></div>
<p>Furthermore did we fix the behavior of relative spec or exclude paths. Before <code>v8</code> every path within <code>specs</code>, <code>exclude</code> or <code>--spec</code> was always seen relative from the users working directory. This behavior was confusing especially when the <code>wdio.conf.js</code> was not within the root of you project. This got fixed now so that <code>specs</code> and <code>exclude</code> path will be always seen as relative to the config file and <code>--spec</code> arguments, relative from the working directory.</p>
<p>Lastly, we had to remove support for <a href="https://www.npmjs.com/package/tsconfig-paths" target="_blank" rel="noopener noreferrer" class="">tsconfig-paths</a> as we haven't found a way to get it working within an ESM context. We believe this integration hasn't been used much anyway and a lot of it is nowadays natively supported in TypeScript. Let us know if this assumption is wrong and you would like to see it being supported again.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="whats-next">What's Next?<a href="https://webdriver.io/de/blog/2022/12/01/webdriverio-v8-released#whats-next" class="hash-link" aria-label="Direkter Link zu What's Next?" title="Direkter Link zu What's Next?" translate="no">​</a></h2>
<p>The WebdriverIO team is very excited about this release as it frees up time to start working on some new cool features we put on the <a href="https://github.com/webdriverio/webdriverio/blob/main/ROADMAP.md" target="_blank" rel="noopener noreferrer" class="">roadmap</a>. For many months we have been working secretly on a VS Code Extension that makes authoring and debugging tests much easier. Aside from that, there is always plenty more work to do and opportunities to explore to make this project better. We are welcoming and supporting everyone who likes to join us.</p>
<p>Lastly, I would like to say thank you to everyone who supports the project. Not only the folks who contribute financially through <a href="https://opencollective.com/webdriverio" target="_blank" rel="noopener noreferrer" class="">Open Collective</a> or <a href="https://tidelift.com/lifter/search/npm/webdriverio" target="_blank" rel="noopener noreferrer" class="">Tidelift</a> but also everyone who contributes code, ideas, reports issues or supports folks in our <a href="https://discord.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">support chat</a>, occasionally or on regular basis. Without contributions from the community, this project can't go anywhere. Aside from many alternative projects WebdriverIO is not funded, nor driven by any corporate interest and stays 100% community governed. No lack of funding or need for capital gains will have an impact on this project. It has been like this since its inception more than 10 years ago and will continue to be like this for many many more years. Therefore we are always looking for interested folks who like to help us hack on the project. If you haven't, join our <a href="https://webdriver.io/community/openofficehours" target="_blank" rel="noopener noreferrer" class="">Open Office Hours</a> and consider giving back to the project.</p>
<p>I am looking forward to more years and great features ahead. Thanks for reading!</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Keep Your Apps Accessible and Your e2e Tests Stable With WebdriverIOs New Accessibility Selector]]></title>
        <id>https://webdriver.io/de/blog/2022/09/05/accessibility-selector</id>
        <link href="https://webdriver.io/de/blog/2022/09/05/accessibility-selector"/>
        <updated>2022-09-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Fetching elements within e2e tests can sometimes be very hard. Complex CSS paths or arbitrary test ids make them either less readable or prone to failures. The disappointment we experience when our test fail is by far not comparable to a the bad experience people have when they need to use assistent devices like screen readers on applications build without accessibility in mind.]]></summary>
        <content type="html"><![CDATA[<p>Fetching elements within e2e tests can sometimes be very hard. Complex CSS paths or arbitrary test ids make them either less readable or prone to failures. The disappointment we experience when our test fail is by far not comparable to a the bad experience people have when they need to use assistent devices like screen readers on applications build without accessibility in mind.</p>
<p>With the accessibility selector introduced in version <code>v7.24.0</code> WebdriverIO now provides a powerful way to fetch various of elements containing a certain accessibility name. Rather than applying arbitrary <code>data-testId</code> properties to elements which won't be recognised by assistent devices, developers or QA engineers can now either apply a correct accessibility name to the element themselves or ask the development team to improve the accessibility so that writing tests becomes easier.</p>
<p>WebdriverIO internally uses a chain of xPath selector conditions to fetch the correct element. While the framework has no access to the accessibility tree of the browser, it can only guess the correct name here. As accessibility names are computed based on author supplied names and content names, WebdriverIO fetches an element based in a certain order:</p>
<ol>
<li class="">First we try to find an element that has an <code>aria-labelledBy</code> or <code>aria-describedBy</code> property pointing to an element containing a valid id, e.g.:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">h2</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">social</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">Social Media</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">h2</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">nav</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">aria-labelledBy</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">social</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">...</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">nav</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<!-- -->So we can fetch a certain link within our navigation via:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/Social Media'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'a=API'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">Then we look for elements with a certain <code>aria-label</code>, e.g.:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">button</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">aria-label</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">close button</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">X</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">button</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<!-- -->Rather than using <code>X</code> to fetch the element or applying a test id property we can just do:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/close button'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">Well defined HTML forms provide a label to every input element, e.g.:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">label</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">for</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">username</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">Username</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">label</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">input</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">username</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">text</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><br></span></code></pre></div></div>
<!-- -->Setting the value of the input can now be done via:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/Username'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">setValue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'foobar'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">Less ideal but still working are <code>placeholder</code> or <code>aria-placeholder</code> properties:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">input</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">Your Username</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">text</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><br></span></code></pre></div></div>
<!-- -->Which can now be used to fetch elements as well:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/Your Username'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">setValue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'foobar'</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
</li>
<li class="">Furthermore if an image tag provides a certain alternative text, this can be used to query that element as well, e.g.:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">img</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">alt</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">A warm sommer night</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">src</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">...</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><br></span></code></pre></div></div>
<!-- -->Such an image can be now fetched via:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/A warm sommer night'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getTagName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// outputs "img"</span><br></span></code></pre></div></div>
</li>
<li class="">Lastly, if no proper accessibility name can be derived, it is computed by its accumulated text, e.g.:<!-- -->
<div class="language-html codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-html codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">h1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain">Welcome!</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">h1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<!-- -->Such a heading tag can be now fetched via:<!-- -->
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'aria/Welcome!'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getTagName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// outputs "h1"</span><br></span></code></pre></div></div>
</li>
</ol>
<p>As you can see, there are a variety of ways to define the accessibility name of an element. Many of the browser debugging tools provide handy accessibility features that help you to find the proper name of the element:</p>
<p><img decoding="async" loading="lazy" alt="Getting Accessibility Name in Chrome DevTools" src="https://webdriver.io/de/assets/images/ally-c1fc0a131f8c5035c70fafcd415f5c54.png" width="1892" height="1134" class="img_ahPx"></p>
<blockquote>
<p>For more information check out the <a href="https://developer.chrome.com/docs/devtools/accessibility/reference/#pane" target="_blank" rel="noopener noreferrer" class="">Chrome DevTools</a> or <a href="https://firefox-source-docs.mozilla.org/devtools-user/accessibility_inspector/" target="_blank" rel="noopener noreferrer" class="">Firefox Accessibility Inspector</a> docs.</p>
</blockquote>
<p>Accessibility is not only a powerful tool to create an inclusive web, it can also help you write stable and readable tests. While you should <strong>not</strong> go ahead and give every element an <code>aria-label</code>, this new selector can help you build web applications with accessibility in mind so that writing e2e tests for it later on will become much easier.</p>
<p>Thanks for reading!</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[WebdriverIO, meet Serenity/JS]]></title>
        <id>https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js</id>
        <link href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js"/>
        <updated>2021-08-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[WebdriverIO is one of the most popular test frameworks and an excellent Web integration tool.]]></summary>
        <content type="html"><![CDATA[<p>WebdriverIO is one of the most popular test frameworks and an excellent Web integration tool.</p>
<p>In fact, it's one of my favourites ❤️</p>
<p>But, to write <strong>truly great acceptance tests</strong> you need more than that:</p>
<ul>
<li class="">You need <strong>business-friendly abstractions</strong> that capture the language of your domain and make even the most sophisticated, multi-actor, and cross-system workflows easy to design and adapt as the requirements change.</li>
<li class="">You need <strong>in-depth reporting</strong> that tells you not only what tests were executed, but also what requirements and business capabilities have (and have not!) been tested.</li>
<li class="">And on top of that, you need to be able to interact with <strong>all the interfaces</strong> of your system, so that the slower UI-based interactions are just one tool in your testing toolbox, rather than your only option.</li>
</ul>
<p>Of course, all the above is way outside of the scope of what WebdriverIO is trying to accomplish.</p>
<p>Typically, you and your team would need to figure it out all by yourselves.</p>
<p>But, what if I told you that there was a <strong>better way</strong>? That there was another framework that's perfectly compatible with WebdriverIO and optimised to help you write <strong>world-class, full-stack acceptance tests</strong> following the <a href="https://serenity-js.org/handbook/design/screenplay-pattern.html" target="_blank" rel="noopener noreferrer" class="">Screenplay Pattern</a> and <a href="https://en.wikipedia.org/wiki/SOLID" target="_blank" rel="noopener noreferrer" class="">SOLID</a> design principles, even if not everyone on your team is an experienced test engineer?</p>
<p>What if I told you that this framework also covers <strong>business-friendly reporting</strong> and helps you write <strong>high-quality test code</strong> that's <strong>easy to understand</strong>, <strong>maintain</strong>, and <strong>reuse across projects and teams</strong>?</p>
<p>What if I told you that you could add it to your <strong>existing WebdriverIO test suites</strong>, today?</p>
<p>Please allow me to introduce, <a href="https://serenity-js.org/" target="_blank" rel="noopener noreferrer" class="">Serenity/JS</a>!</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="about-serenityjs">About Serenity/JS<a href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js#about-serenityjs" class="hash-link" aria-label="Direkter Link zu About Serenity/JS" title="Direkter Link zu About Serenity/JS" translate="no">​</a></h3>
<p><a href="https://serenity-js.org/" target="_blank" rel="noopener noreferrer" class="">Serenity/JS</a> is an open-source <strong>acceptance testing</strong> and <strong>integration framework</strong>, designed to make writing truly great acceptance tests <strong>easier</strong>, <strong>more collaborative</strong>, and <strong>fun</strong>! 🚀</p>
<p>While you can use Serenity/JS to test systems of any complexity, it works particularly well in complex, workflow-based, multi-actor contexts.</p>
<p>At a high level, Serenity/JS is a modular framework that provides <a href="https://serenity-js.org/modules/" target="_blank" rel="noopener noreferrer" class="">adapters</a> that make it easy to integrate your tests with <a href="https://serenity-js.org/modules/webdriverio/" target="_blank" rel="noopener noreferrer" class="">Web apps</a>, <a href="https://serenity-js.org/modules/rest/" target="_blank" rel="noopener noreferrer" class="">REST APIs</a>, <a href="https://serenity-js.org/modules/local-server/" target="_blank" rel="noopener noreferrer" class="">Node.js servers</a>, and <a href="https://serenity-js.org/handbook/integration/architecture.html" target="_blank" rel="noopener noreferrer" class="">pretty much anything</a> a Node.js program can talk to.</p>
<p>Thanks to Serenity/JS <a href="https://serenity-js.org/handbook/design/screenplay-pattern.html" target="_blank" rel="noopener noreferrer" class="">Screenplay Pattern</a>, you and your team will also have a simple, consistent, and <strong>async-friendly</strong> <a href="https://serenity-js.org/handbook/thinking-in-serenity-js/index.html" target="_blank" rel="noopener noreferrer" class="">programming model</a> across all those interfaces.</p>
<p>Apart from integrating with your system under test, Serenity/JS can also integrate with popular test runners such as <a href="https://serenity-js.org/modules/cucumber/" target="_blank" rel="noopener noreferrer" class="">Cucumber</a>, <a href="https://serenity-js.org/modules/jasmine/" target="_blank" rel="noopener noreferrer" class="">Jasmine</a>, <a href="https://serenity-js.org/modules/mocha/" target="_blank" rel="noopener noreferrer" class="">Mocha</a>, <a href="https://serenity-js.org/modules/protractor/" target="_blank" rel="noopener noreferrer" class="">Protractor</a>, and now also <a href="https://serenity-js.org/modules/webdriverio/" target="_blank" rel="noopener noreferrer" class="">WebdriverIO</a>!</p>
<p>Better yet, Serenity/JS provides a unique <a href="https://serenity-js.org/handbook/reporting/index.html" target="_blank" rel="noopener noreferrer" class="">reporting system</a> to help you generate consistent test execution and feature coverage reports across all the interfaces of your system and across all your test suites.
Serenity/JS reporting services can work together with your existing WebdriverIO reporters too!</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="thinking-in-serenityjs">Thinking in Serenity/JS<a href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js#thinking-in-serenityjs" class="hash-link" aria-label="Direkter Link zu Thinking in Serenity/JS" title="Direkter Link zu Thinking in Serenity/JS" translate="no">​</a></h3>
<p>The best way to get started with Serenity/JS is to follow our brand-new series of tutorials, where you'll learn how to build full-stack test automation frameworks from scratch.</p>
<p>Check out <a href="https://serenity-js.org/handbook/thinking-in-serenity-js/index.html" target="_blank" rel="noopener noreferrer" class="">"Thinking in Serenity/JS"</a> 🤓</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="examples-and-project-templates">Examples and project templates<a href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js#examples-and-project-templates" class="hash-link" aria-label="Direkter Link zu Examples and project templates" title="Direkter Link zu Examples and project templates" translate="no">​</a></h3>
<p>If you prefer to kick the tires and jump straight into the code, you'll find <a href="https://github.com/serenity-js/serenity-js/tree/master/examples" target="_blank" rel="noopener noreferrer" class="">over a dozen example projects</a> in the <a href="https://github.com/serenity-js/serenity-js" target="_blank" rel="noopener noreferrer" class="">Serenity/JS GitHub repository</a> and plenty of code samples in our <a href="https://serenity-js.org/modules/webdriverio/" target="_blank" rel="noopener noreferrer" class="">API docs</a>.</p>
<p>We've also created WebdriverIO + Serenity/JS project templates to help you get started:</p>
<ul>
<li class=""><a href="https://github.com/serenity-js/serenity-js-cucumber-webdriverio-template/" target="_blank" rel="noopener noreferrer" class="">WebdriverIO, Serenity/JS and Cucumber</a></li>
<li class=""><a href="https://github.com/serenity-js/serenity-js-mocha-webdriverio-template/" target="_blank" rel="noopener noreferrer" class="">WebdriverIO, Serenity/JS and Mocha</a></li>
</ul>
<p>All the above templates are configured to produce <strong>Serenity BDD HTML reports</strong>, <strong>automatically capture screenshots</strong> upon test failure, and run in a <strong>Continuous Integration</strong> environment.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="adding-serenityjs-to-an-existing-project">Adding Serenity/JS to an existing project<a href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js#adding-serenityjs-to-an-existing-project" class="hash-link" aria-label="Direkter Link zu Adding Serenity/JS to an existing project" title="Direkter Link zu Adding Serenity/JS to an existing project" translate="no">​</a></h3>
<p>If you're using WebdriverIO with Mocha, run the following command in your computer terminal to add the relevant <a href="https://serenity-js.org/modules" target="_blank" rel="noopener noreferrer" class="">Serenity/JS modules</a> to your project:</p>
<div class="language-shell codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-shell codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">npm install --save-dev @serenity-js/{code,console-reporter,mocha,webdriverio}</span><br></span></code></pre></div></div>
<p>If you're using Cucumber or Jasmine instead, replace <a href="https://serenity-js.org/modules/mocha" target="_blank" rel="noopener noreferrer" class=""><code>mocha</code></a> with the name of your preferred test runner, so <a href="https://serenity-js.org/modules/cucumber" target="_blank" rel="noopener noreferrer" class=""><code>cucumber</code></a> or <a href="https://serenity-js.org/modules/jasmine" target="_blank" rel="noopener noreferrer" class=""><code>jasmine</code></a>, respectively.</p>
<p>Next, tell WebdriverIO to use Serenity/JS instead of the default framework adapter:</p>
<div class="language-ts codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-ts codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> ConsoleReporter </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@serenity-js/console-reporter'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> WebdriverIOConfig </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@serenity-js/webdriverio'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> config</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> WebdriverIOConfig </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Enable Serenity/JS framework adapter</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// see: https://serenity-js.org/modules/webdriverio/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    framework</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@serenity-js/webdriverio'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    serenity</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Use Serenity/JS test runner adapter for Mocha</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        runner</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'mocha'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// see: https://serenity-js.org/modules/mocha/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// runner: 'jasmine',   // see: https://serenity-js.org/modules/jasmine/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// runner: 'cucumber',  // see: https://serenity-js.org/modules/cucumber/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// Configure reporting services</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic">// see: https://serenity-js.org/handbook/reporting/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        crew</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ConsoleReporter</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">forDarkTerminals</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ... other WebdriverIO configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>And that's it!</p>
<p>The above configuration enables <a href="https://serenity-js.org/modules/console-reporter" target="_blank" rel="noopener noreferrer" class="">Serenity/JS Console Reporter</a>, which produces output similar to the below and plays nicely with any existing WebdriverIO reporters you might have already configured:</p>
<p><img decoding="async" loading="lazy" alt="Serenity/JS Console Reporter output" src="https://webdriver.io/de/assets/images/serenity-js-console-reporter-output-db6b230339603c123e360a3acac8545f.png" width="2166" height="1200" class="img_ahPx"></p>
<p>To enable <strong>Serenity BDD HTML Reporter</strong>, please <a href="https://serenity-js.org/handbook/reporting/serenity-bdd-reporter.html" target="_blank" rel="noopener noreferrer" class="">follow the instructions</a>.</p>
<p>To learn about Serenity/JS <a href="https://serenity-js.org/handbook/design/screenplay-pattern.html" target="_blank" rel="noopener noreferrer" class="">Screenplay Pattern</a>, <a href="https://serenity-js.org/handbook/thinking-in-serenity-js/index.html" target="_blank" rel="noopener noreferrer" class="">follow the tutorial</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_eDRp" id="questions-feedback-ideas">Questions? Feedback? Ideas?<a href="https://webdriver.io/de/blog/2021/08/25/webdriverio-meet-serenity-js#questions-feedback-ideas" class="hash-link" aria-label="Direkter Link zu Questions? Feedback? Ideas?" title="Direkter Link zu Questions? Feedback? Ideas?" translate="no">​</a></h3>
<p>If you have questions about Serenity/JS or need guidance in getting started, join our friendly <a href="https://gitter.im/serenity-js/Lobby" target="_blank" rel="noopener noreferrer" class="">Serenity/JS Community Chat channel</a>.</p>
<p>For project news and updates, follow <a href="https://twitter.com/SerenityJS" target="_blank" rel="noopener noreferrer" class="">@SerenityJS</a> on Twitter.</p>
<p>And if you like Serenity/JS and would like to see more articles on how to use it with WebdriverIO, remember to give us a ⭐ on <a href="https://github.com/serenity-js/serenity-js" target="_blank" rel="noopener noreferrer" class="">Serenity/JS GitHub</a>! 😊</p>
<p>Enjoy Serenity!</p>
<p>Jan</p>]]></content>
        <author>
            <name>Jan Molak</name>
            <uri>https://www.linkedin.com/in/janmolak/</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Sync API Deprecation]]></title>
        <id>https://webdriver.io/de/blog/2021/07/28/sync-api-deprecation</id>
        <link href="https://webdriver.io/de/blog/2021/07/28/sync-api-deprecation"/>
        <updated>2021-07-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[For many years one of the selling features of the WebdriverIO framework was its synchronous API. Especially for folks coming from more synchronous oriented languages such as Java or Ruby, it has helped to avoid race conditions when executing commands. But also people that are more familiar with Promises tend to prefer synchronous execution as it made the code easier to read and handle.]]></summary>
        <content type="html"><![CDATA[<p>For many years one of the selling features of the WebdriverIO framework was its synchronous API. Especially for folks coming from more synchronous oriented languages such as Java or Ruby, it has helped to avoid race conditions when executing commands. But also people that are more familiar with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener noreferrer" class="">Promises</a> tend to prefer synchronous execution as it made the code easier to read and handle.</p>
<p>Running asynchronous commands in a synchronous way was possible with the help of the <a href="https://www.npmjs.com/package/@wdio/sync" target="_blank" rel="noopener noreferrer" class=""><code>@wdio/sync</code></a> package. If installed, WebdriverIO would automatically wrap the commands with utility methods that were using the <a href="https://www.npmjs.com/package/fibers" target="_blank" rel="noopener noreferrer" class=""><code>fibers</code></a> package to create a synchronous execution environment. It uses some internal V8 APIs to allow to jump between multiple call stacks from within a single thread. This approach also has been popular among other projects, e.g. <a href="https://www.meteor.com/" target="_blank" rel="noopener noreferrer" class="">Meteor</a>, where most of the code is written using asynchronous APIs which causes developers to constantly start the line of code with <code>await</code>.</p>
<p>Last year the <a href="https://github.com/laverdet" target="_blank" rel="noopener noreferrer" class="">author</a> of the Fibers package <a href="https://github.com/laverdet/node-fibers/commit/e2a0ed9c6d985f94c2b1947eaf72d5797e8a3278" target="_blank" rel="noopener noreferrer" class="">announced</a> that he would no longer continue to maintain the project anymore. He built Fibers when JavaScript did not have any proper mechanism to handle asynchronous code other than using callbacks. With JavaScript evolving and adding APIs like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener noreferrer" class="">Promises</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator" target="_blank" rel="noopener noreferrer" class="">Generators</a> there is technically no reason anymore for Fibers to exist other than preference of code style. Now with the release of Node.js v16 and the update to <a href="https://v8.dev/" target="_blank" rel="noopener noreferrer" class="">V8</a> v9 Fibers stopped working due to a <a href="https://chromium-review.googlesource.com/c/v8/v8/+/2537690" target="_blank" rel="noopener noreferrer" class="">change in V8</a> that would remove some internal interfaces Fibers was using. Given that a fix for this is non trivial and the maintainer already stepped down from the project it is unlikely that we will see support for Fibers in Node.js v16 and on.</p>
<p>After the WebdriverIO team discovered this we immediately took action and evaluated our options. We opened an <a href="https://github.com/webdriverio/webdriverio/discussions/6702" target="_blank" rel="noopener noreferrer" class="">RFC</a> to discuss with the community in which direction the project should go. I would like to thank everyone who chimed in and provided their opinion. We experimented with some alternative options, e.g. using Babel to transpile synchronous code into asynchronous but they all failed due to various reasons. The ultimate decision was made to accept the fact that synchronous command execution won't be possible moving on and rather embrace asynchronicity.</p>
<p>With the release of WebdriverIO <code>v7.9</code> we are happy to announce that we improved our asynchronous API and matched it with the synchronous one. When chaining element command calls users had to write aweful code like this before:</p>
<div class="language-js codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-js codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#foo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">$$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'.bar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>now this got simiplified to this:</p>
<div class="language-js codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-js codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'#foo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">$$</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'.bar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">42</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">click</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>Thanks to the enormous power of the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy" target="_blank" rel="noopener noreferrer" class="">Proxy Object</a> the API is now much more streamlined and less verbose. This will also help users migrating a project that uses the synchronous API to become asynchronous. The team will work on a <a href="https://github.com/webdriverio/codemod/issues/1" target="_blank" rel="noopener noreferrer" class="">codemod</a> to help make this process as automated and easy as possible.</p>
<p>At this point the WebdriverIO team wants to thank Marcel Laverdet (<code>@laverdet</code> on <a href="https://github.com/laverdet" target="_blank" rel="noopener noreferrer" class="">GitHub</a>) for building Fibers and maintaining it for so many years. It is time to move on and embrace all the great JavaScript language feature many people have worked hard on. While we have updated the code examples in our docs, <code>@wdio/sync</code> will continue to be supported until we drop support for Node.js v14 and earlier which won't happen before April 2023. You will have enough time to slowly migrate your tests using <code>async/await</code>.</p>
<p>If you have any questions on this or the migration from a framework writing with synchronous commands to asynchronous code, feel free to drop us a line in our <a href="https://github.com/webdriverio/webdriverio/discussions/new" target="_blank" rel="noopener noreferrer" class="">discussion forum</a> or on our community <a href="https://discord.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">Discord</a> support server.</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Case Study - How WebdriverIO facilitated faster releases and better code quality for an online video company]]></title>
        <id>https://webdriver.io/de/blog/2021/06/22/jwplayer-case-study</id>
        <link href="https://webdriver.io/de/blog/2021/06/22/jwplayer-case-study"/>
        <updated>2021-06-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[JW Player is an embeddable, online video player which generates over a billion unique views every day. In order to sustain and grow this scale, the player needs to be able to function on a multitude of different web and mobile platforms. This increases the importance of automated testing to improve confidence in our releases when deploying to so many different targets. After a lengthy project of converting our legacy test framework, which comprised over 6,000 tests, the Test Engineering team at JW Player has been able to deliver more timely releases with fewer regressions. We have experienced no major rollbacks, and increased the confidence we have in the quality of our own product, thanks to WebdriverIO.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://www.jwplayer.com/" target="_blank" rel="noopener noreferrer" class="">JW Player</a> is an embeddable, online video player which generates over a billion unique views every day. In order to sustain and grow this scale, the player needs to be able to function on a multitude of different web and mobile platforms. This increases the importance of automated testing to improve confidence in our releases when deploying to so many different targets. After a lengthy project of converting our legacy test framework, which comprised over 6,000 tests, the Test Engineering team at JW Player has been able to deliver more timely releases with fewer regressions. We have experienced no major rollbacks, and increased the confidence we have in the quality of our own product, thanks to WebdriverIO.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="choosing-webdriverio">Choosing WebdriverIO<a href="https://webdriver.io/de/blog/2021/06/22/jwplayer-case-study#choosing-webdriverio" class="hash-link" aria-label="Direkter Link zu Choosing WebdriverIO" title="Direkter Link zu Choosing WebdriverIO" translate="no">​</a></h2>
<p>Before our migration to WebdriverIO, we had been using an open sourced Ruby framework on top of Cucumber. JW Player is officially supported on seven desktop and mobile web browsers, as well as iOS and Android versions dating back to 10 and 4.4, respectively. For coverage of these platforms, we run approximately 25,000 UI acceptance tests on a nightly basis. The legacy implementation created two problems. First, we encountered performance limitations in Ruby, as a single test run across all platforms could take up to 9 hours. Second, as the Player is implemented in JavaScript, product engineers were less likely to embrace and contribute to the Ruby-based framework. Moving to a JavaScript-native framework addressed both of these problems.</p>
<p>Selenium Webdriver has long been the go-to standard for web automation. Around 2018, our team began to explore several new emerging testing technologies. Cypress had limited browser support, Microsoft Playwright had not yet even been released, and Puppeteer would only execute on Chrome. A Webdriver-based solution, with its broad and dedicated support amongst browser vendors, was the clear winner.</p>
<p>What initially attracted us to WebdriverIO was its straightforward API and complete support for all browsers and devices we needed to test, compared to Cypress and Puppeteer which lack support for one or more of the necessary platforms. More importantly, though, was its rich plugin system and active, engaged developer community. Sponsorship from Sauce Labs, which had already made a name for itself within the testing space, gave us confidence that WebdriverIO would continue to grow and not become abandonware.</p>
<p>Out of the box, WebdriverIO had support for several of our existing and desired toolsets. Tools such as <a href="https://webdriver.io/docs/allure-reporter" target="_blank" rel="noopener noreferrer" class="">Allure reporting</a>, which we use to quickly comb through product defects, as well as <a href="https://webdriver.io/docs/wdio-reportportal-reporter" target="_blank" rel="noopener noreferrer" class="">Report Portal</a>, which we use to monitor test health and track trends over time, were easy for us to integrate. The granular <a href="https://webdriver.io/docs/options/#hooks" target="_blank" rel="noopener noreferrer" class="">pre and post execution hooks</a> gave the test engineers an unprecedented ability to shape how and where tests executed.</p>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="webdriverio-practical-approach">Webdriver.IO Practical Approach<a href="https://webdriver.io/de/blog/2021/06/22/jwplayer-case-study#webdriverio-practical-approach" class="hash-link" aria-label="Direkter Link zu Webdriver.IO Practical Approach" title="Direkter Link zu Webdriver.IO Practical Approach" translate="no">​</a></h2>
<p>As more features keep being added to WebdriverIO, we are continually able to simplify our codebase by removing open source dependencies and messy mixin code. We have even been able to decommission services that our old framework relied on altogether.</p>
<ul>
<li class="">
<p>The <a href="https://webdriver.io/blog/2020/07/10/network-primitives" target="_blank" rel="noopener noreferrer" class="">Network Primitives feature</a>, released last year, allowed us to remove our dependency on Browsermob Proxy, a proxy tool commonly used in Selenium Webdriver applications to intercept and manipulate HTTP requests. We now call <code>browser.mock()</code>, specify a substring or regex of the request we want to capture and supply a simple mock object to replace the asset. The ability to delay a response allowed us to automate several complicated tests which had required manual execution. We were then able to validate the player’s behavior when particular requests, such as ads, are delayed due to network or other external conditions:</p>
<div class="language-text codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-text codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">// mock.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">export function delayResponse3seconds() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    return new Promise((resolve) =&gt; setTimeout(() =&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        return resolve('{ "foo": bar }');</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }, 3000));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// test.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import { delayResponse3seconds } from './mock';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function rewritePattern(pattern, replacement) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   console.log(`Attempting to rewrite: ${pattern} with: ${replacement}`);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   const toRewrite = browser.mock(`**/${pattern}`);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   toRewrite.respond(delayResponse3seconds);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   console.log(`Successfully rewrote ${pattern} to ${replacement}`);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>The <a href="https://webdriver.io/docs/api/chromium" target="_blank" rel="noopener noreferrer" class="">Chrome Devtools Protocol</a> support that comes out of the box has also enabled us to automate some tests that were a manual chore. Being able to call <code>browser.throttle(“Good3G”)</code> after our initial page load has allowed us to more accurately verify how the video player behaves under more real world conditions for our mobile users.</p>
</li>
<li class="">
<p>Thanks to <a href="https://webdriver.io/docs/devtools-service/#getmetrics" target="_blank" rel="noopener noreferrer" class="">WebdriverIO’s CDP mapping</a>, we have been able to create and maintain a suite of performance tests. Calling <code>browser.getMetrics()</code> after a page load and interacting with the player has enabled us to verify that once a player is set up and embedded onto a customer’s website, it will not cause any undue Cumulative Layout Shifts for the end user, which create a disruptive page loading experience.</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_eDRp" id="summary">Summary<a href="https://webdriver.io/de/blog/2021/06/22/jwplayer-case-study#summary" class="hash-link" aria-label="Direkter Link zu Summary" title="Direkter Link zu Summary" translate="no">​</a></h2>
<p>Overall, JW Player’s migration to WebdriverIO was nothing short of a huge success. Between the performance and “quality of life” improvements over our old framework, WebdriverIO’s feature set has allowed us to automate a couple of hundred manual test cases. We've been able to greatly cut down the length of our regression cycles from approximately 1 week to just a couple of days. Most importantly, however, these improvements have allowed us to find a record number of defects, leading to a better quality product and delivering more customer value.</p>]]></content>
        <author>
            <name>Eric Saari</name>
            <uri>https://www.linkedin.com/in/esaari/</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[WebdriverIO Opens an OpenCollective]]></title>
        <id>https://webdriver.io/de/blog/2021/03/31/open-collective</id>
        <link href="https://webdriver.io/de/blog/2021/03/31/open-collective"/>
        <updated>2021-03-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today the WebdriverIO team announced in their OpenJS Foundation Q&A session that the project opens an OpenCollective to allow users and companies to donate to the development of the project and support community members to run WebdriverIO workshops and other types of events. This allows everyone to be paid to work on features and bug fixes as well as help the community to pay for pizza or rental space when hosting WebdriverIO workshops or meetups.]]></summary>
        <content type="html"><![CDATA[<p>Today the WebdriverIO team announced in their <a href="https://openjsf.org/" target="_blank" rel="noopener noreferrer" class="">OpenJS Foundation</a> Q&amp;A session that the project opens an <a href="https://opencollective.com/webdriverio" target="_blank" rel="noopener noreferrer" class="">OpenCollective</a> to allow users and companies to donate to the development of the project and support community members to run WebdriverIO workshops and other types of events. This allows everyone to be paid to work on features and bug fixes as well as help the community to pay for pizza or rental space when hosting WebdriverIO workshops or meetups.</p>
<p>If your company uses WebdriverIO and benefits from it, please ask your manager or your marketing team to support the project by donating to the collective. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone.</p>
<p>As part of this we also like to announce the official WebdriverIO Swag Store: <a href="http://shop.webdriver.io/" target="_blank" rel="noopener noreferrer" class="">shop.webdriver.io</a>, which will be used as an income source for the collective. All purchases from that store will directly go into our fund and to you. We start our collection with a T-shirt, a sweatshirt and a couple of accessories but will soon extend to more. So stay tuned!</p>
<p>We want to be transparent in the way we accept expenses to the collective. Everyone should be eligible to participate and send in expenses for development on certain features. We also want to give back to the community by allowing us to expense event expenses. The following expense types may be eligible to be reimbursed from the collective:</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="event-expenses">Event Expenses<a href="https://webdriver.io/de/blog/2021/03/31/open-collective#event-expenses" class="hash-link" aria-label="Direkter Link zu Event Expenses" title="Direkter Link zu Event Expenses" translate="no">​</a></h4>
<p>If you host an event that has a speaker talking about using WebdriverIO and it's features you can expense up to <strong>$100</strong>. Reimbursement requirements for event expenses include:</p>
<ul>
<li class="">You or the event account must share the project on social media (Twitter, Facebook or LinkedIn) at least 3x</li>
<li class="">The event page must have the WebdriverIO logo and a link to the project page in your meetup description</li>
<li class="">You must use the funds for qualified event expenses such as food, beverage, room or equipment rental.</li>
<li class="">You must submit receipts with your reimbursement request.</li>
</ul>
<p>Our goal with this expense policy is to help the community to run events, to promote the project and support anyone learning about WebdriverIO. We've already seen project meetups happening in New York and The Netherlands and hope to see more of this in the future.</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="development-expenses">Development Expenses<a href="https://webdriver.io/de/blog/2021/03/31/open-collective#development-expenses" class="hash-link" aria-label="Direkter Link zu Development Expenses" title="Direkter Link zu Development Expenses" translate="no">​</a></h4>
<p>If you have done development work on any of the repositories within the GitHub WebdriverIO organisation you may reimburse up to <strong>$1000</strong> if the following requirements are met:</p>
<ul>
<li class="">You must have submitted qualifying pull requests that have closed at least 10 issues that were labeled with <a href="https://github.com/webdriverio/webdriverio/labels/Expensable%20%F0%9F%92%B8" target="_blank" rel="noopener noreferrer" class=""><code>Expensable 💸</code></a></li>
<li class="">Every additional issue closed with that label can be expensed with $100</li>
<li class="">You must submit links to all issues you’ve closed due to your pull requests</li>
<li class="">In order to close the ticket automatically, you must have one commit message with the Fix keyword. For example, Fix #1234 to close ticket #1234.</li>
<li class="">Pull Requests must be merged by someone from the <a href="https://github.com/webdriverio/webdriverio/blob/main/AUTHORS.md#tsc-technical-steering-committee" target="_blank" rel="noopener noreferrer" class="">core team</a>. If there are several Pull Requests, the core team member either selects the most recent one or the best one - that’s up to them to decide what is best for the project.</li>
<li class="">You must claim an <a href="https://github.com/webdriverio/webdriverio/labels/Expensable%20%F0%9F%92%B8" target="_blank" rel="noopener noreferrer" class=""><code>Expensable 💸</code></a> issue by commenting to the issue thread to ensure that no one else is working on the same issue.</li>
<li class="">Anyone contributing to WebdriverIO is eligible to expense their work if the implemented features or bug fixes are not objectives of a commercial job.</li>
</ul>
<p>Please note that contributing on behalf of a company does not make you eligible to also get reimbursed by the collective. If a company pays you to work on WebdriverIO we see this already as a contribution to the project by the company.</p>
<p>We understand that $1000 for fixing 10 bugs or implementing 10 features may seem arbitrary because some work items will take longer than others. However by requiring someone to finish 10 work items we hope that this uncertainty of effort and time will balance out. We also understand that this will not reimburse someone by their market value and it certainly won't allow someone to work full time on WebdriverIO. The goal of the collective is to reimburse people that usually would contribute in their free time in a very transparent and open way.</p>
<h4 class="anchor anchorTargetStickyNavbar_eDRp" id="travel-expenses">Travel Expenses<a href="https://webdriver.io/de/blog/2021/03/31/open-collective#travel-expenses" class="hash-link" aria-label="Direkter Link zu Travel Expenses" title="Direkter Link zu Travel Expenses" translate="no">​</a></h4>
<p>If you are a member of the <a href="https://github.com/webdriverio/webdriverio/blob/main/AUTHORS.md#tsc-technical-steering-committee" target="_blank" rel="noopener noreferrer" class="">Technical Steering Committee team</a> you are eligible to expense flights and hotel accommodations for travel to conferences or meetups as part of a speaking engagement on WebdriverIO, not paid by the event itself or a company. You may expense up to $500. Reimbursement requirements for travel expenses include:</p>
<ul>
<li class="">You must send out a post from your main social media account (e.g. Twitter, LinkedIn or personal blog) thanking all contributors of the collective after the event took place.</li>
<li class="">You must use the funds for qualified travel expenses such as ground or air transportation to the event and hotel accommodations.</li>
<li class="">You must submit receipts with your reimbursement request.</li>
</ul>
<p>Even though currently there are no in-person events happening due to the COVID-19 pandemic, we hope that we come back to times where we can reconnect with the community on a personal level. For that we would like to support the core team with their travel expenses.</p>
<p>Overall we hope that this expense policy is fair and inclusive enough that anyone can participate. Opening a collective might sound easy in the beginning but doesn't end up being a trivial effort when you consider transparency and fairness. We expect to make amendments to our policies once we gather more experience from the process.</p>
<p>Thank you to everyone who will donate money to the collective and therefore will support the project and everyone contributing to it. It really means a lot ❤️</p>]]></content>
        <author>
            <name>Christian Bromann</name>
            <uri>http://x.com/bromann</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Grouping Specs for Execution in a Single Instance]]></title>
        <id>https://webdriver.io/de/blog/2021/03/23/grouping-specs</id>
        <link href="https://webdriver.io/de/blog/2021/03/23/grouping-specs"/>
        <updated>2021-03-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Until now, WebdriverIO has created a separate instance to run each of the spec files. So, if we have a directory structure that looks something like this:]]></summary>
        <content type="html"><![CDATA[<p>Until now, WebdriverIO has created a separate instance to run each of the spec files. So, if we have a directory structure that looks something like this:</p>
<div class="language-text codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-text codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">test</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> └─── specs</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         │  test_login.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         │  test_product_order.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         │  test_checkout.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         │  test_b1.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">         │  test_b2.js</span><br></span></code></pre></div></div>
<p>and the config file has specs defined as follows:</p>
<div class="language-json codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-json codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"specs"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        './test/specs/test*.js'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><br></span></code></pre></div></div>
<p>then when WebdriverIO is run, the specs definition will be expanded to create a list of all the test files, and a separate instance will be created to run each test (up to the value of "maxInstances").  Remaining tests will be queued until tests complete.  Consequently, each test is run in its own instance.</p>
<p>This model has many advantages.  It means that tests can be run in parallel and makes it easier to retry tests that fail etc.</p>
<p>However, there are cases where this does not work so well.  In one case a users flow involved transpiling tens of thousands of Typescript files for each of the ~250 test files, resulting in a huge overhead in the speed of the testing.  In another case a remote device farm was provisioning a new device for each test with all the associated setup thereby impacting performance and cost.</p>
<p>At <a href="https://www.vitaq.io/" target="_blank" rel="noopener noreferrer" class="">Vertizan</a> we are integrating our AI-driven and functional coverage-led Vitaq test automation tool with WebdriverIO and Mocha. For Vitaq AI to work, it needs to be able to select which test/action to run next and that requires having all of the tests available in a single instance.</p>
<p>Consequently, we have worked with the WebdriverIO team to implement a syntax which allows the user to specify which tests should be grouped together for execution in the same instance.  All of the three test execution frameworks (Mocha, Jasmine, Cucumber) are supported by this approach, and by default they will run the tests sequentially.</p>
<p>To take advantage of this capability, the definition of the specs in the WDIO config file has been extended so that it can now accept arrays within the specs array. All of the files within an inner array are grouped together and run in the same instance.</p>
<p>So, the following specs definition:</p>
<div class="language-json codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-json codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"specs"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"./test/specs/test_login.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"./test/specs/test_product_order.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"./test/specs/test_checkout.js"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"./test/specs/test_b*.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><br></span></code></pre></div></div>
<p>when run against the previously described directory tree would result in three instances:</p>
<ul>
<li class="">One instance would run the group of test_login.js, test_product_order.js and test_checkout.js</li>
<li class="">Another instance would run test_b1.js</li>
<li class="">A final instance would run test_b2.js</li>
</ul>
<p>It is only the specs definition that supports this syntax.</p>
<p><strong>EDIT:</strong>
This syntax has now been extended to support specs defined in suites, so you can now also define suites like this:</p>
<div class="language-json codeBlockContainer_twka theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_a7CD"><pre tabindex="0" class="prism-code language-json codeBlock_Ujv8 thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_ATNM"><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"suites"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        end2end</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"./test/specs/test_login.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"./test/specs/test_product_order.js"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"./test/specs/test_checkout.js"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        allb</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"./test/specs/test_b*.js"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><br></span></code></pre></div></div>
<p>and in this case all of the tests of the "end2end" suite would be run in a single instance.</p>]]></content>
        <author>
            <name>Ross Addinall</name>
            <uri>http://x.com/rossaddinall</uri>
        </author>
    </entry>
</feed>