<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Talking About Testing</title>
    <description>The latest articles on Forem by Talking About Testing (@talking-about-testing).</description>
    <link>https://forem.com/talking-about-testing</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2961766%2F22e834aa-cf23-4fed-9f2a-fb38c1f76d53.png</url>
      <title>Forem: Talking About Testing</title>
      <link>https://forem.com/talking-about-testing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/talking-about-testing"/>
    <language>en</language>
    <item>
      <title>Triggering Cypress End-to-End Tests Manually on Different Browsers with GitHub Actions</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Fri, 19 Dec 2025 19:29:32 +0000</pubDate>
      <link>https://forem.com/cypress/triggering-cypress-end-to-end-tests-manually-on-different-browsers-with-github-actions-223i</link>
      <guid>https://forem.com/cypress/triggering-cypress-end-to-end-tests-manually-on-different-browsers-with-github-actions-223i</guid>
      <description>&lt;h2&gt;
  
  
  A Practical Guide to Cross-Browser Testing
&lt;/h2&gt;

&lt;p&gt;One of the most practical features of GitHub Actions is the ability to manually trigger workflows and pass parameters at runtime. This is especially useful for end-to-end (E2E) testing, where you may want to select which browser to run the tests against rather than hard-coding that choice.&lt;/p&gt;

&lt;p&gt;In this post, I'll walk you through a GitHub Actions workflow written in YAML that allows you to manually trigger Cypress tests and select the target browser directly from the GitHub UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Full Workflow
&lt;/h3&gt;

&lt;p&gt;Here's the workflow I'll be explaining:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;End-to-end tests 🧪&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests"&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;choice&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chrome&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chrome&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edge&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;electron&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;firefox&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;safari&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cypress-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-24.04&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v6&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install WebKit system deps (Safari)&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.inputs.browser == 'safari' }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx playwright install-deps webkit&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cypress run&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cypress-io/github-action@v6&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test:${{ github.event.inputs.browser }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload screenshots (selected browser, on failure)&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failure()&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;screenshots-${{ github.event.inputs.browser }}&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cypress/screenshots&lt;/span&gt;
          &lt;span class="na"&gt;if-no-files-found&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Naming the Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;End-to-end tests 🧪&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the friendly name shown in the GitHub Actions UI. Adding an emoji is optional, but it makes workflows easier to scan—especially when you have many of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Trigger with &lt;code&gt;workflow_dispatch&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;workflow_dispatch&lt;/code&gt; event enables manual execution of the workflow. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The workflow won't run automatically on &lt;code&gt;push&lt;/code&gt; or &lt;code&gt;pull_request&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A "Run workflow" button will appear in the Actions tab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ad-hoc test runs&lt;/li&gt;
&lt;li&gt;Debugging browser-specific issues&lt;/li&gt;
&lt;li&gt;Running tests before a release&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Defining Input Parameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Browser&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests"&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;choice&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chrome&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chrome&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edge&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;electron&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;firefox&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;safari&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the heart of the workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  What's happening here?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;browser&lt;/code&gt; is a required input&lt;/li&gt;
&lt;li&gt;The user must select one value from a predefined list&lt;/li&gt;
&lt;li&gt;The default option is &lt;code&gt;chrome&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On GitHub, this renders as a dropdown selector in the UI.&lt;/p&gt;

&lt;p&gt;This prevents invalid values and makes the workflow safer and more user-friendly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the Job
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cypress-run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-24.04&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The workflow has a single job called &lt;code&gt;cypress-run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It runs on the &lt;code&gt;ubuntu-24.04&lt;/code&gt; GitHub-hosted runner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ubuntu runners are commonly used for Cypress because they're fast, stable, and well supported by the Cypress GitHub Action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Checking Out the Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step pulls your repository code into the runner so that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cypress tests&lt;/li&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configuration files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are available during execution.&lt;/p&gt;

&lt;p&gt;This step is required in almost every CI workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Installing Safari (WebKit) Dependencies Conditionally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install WebKit system deps (Safari)&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.inputs.browser == 'safari' }}&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx playwright install-deps webkit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an excellent example of conditional execution in GitHub Actions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why is this needed?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Cypress runs Safari tests via WebKit&lt;/li&gt;
&lt;li&gt;WebKit requires additional system dependencies on Linux&lt;/li&gt;
&lt;li&gt;These dependencies are unnecessary for other browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  What the condition does
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;if&lt;/code&gt; expression ensures that this step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs only when &lt;code&gt;safari&lt;/code&gt; is selected&lt;/li&gt;
&lt;li&gt;Is skipped for all other browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps the workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster&lt;/li&gt;
&lt;li&gt;Cleaner&lt;/li&gt;
&lt;li&gt;Easier to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's worth mentioning that for Cypress to work with WebKit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;experimentalWebKitSupport&lt;/code&gt; property has to be set to &lt;code&gt;true&lt;/code&gt; in the &lt;code&gt;cypress.config.js&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;playwright-webkit&lt;/code&gt; has to be installed as a dev dependency (e.g., &lt;code&gt;npm i playwright-webkit -D&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Make sure to version not only the &lt;code&gt;package.json&lt;/code&gt; file, but also the &lt;code&gt;package-lock.json&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Running Cypress with the Selected Browser
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cypress run&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cypress-io/github-action@v6&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test:${{ github.event.inputs.browser }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step uses the official Cypress GitHub Action image.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key idea
&lt;/h4&gt;

&lt;p&gt;The browser input is injected dynamically into the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;:chrome
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:firefox
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:safari
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This implies that your &lt;code&gt;package.json&lt;/code&gt; contains scripts like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:chrome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress run --browser chrome"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:firefox"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress run --browser firefox"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:safari"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress run --browser webkit"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern keeps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The workflow generic&lt;/li&gt;
&lt;li&gt;Browser-specific logic inside your project configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Uploading Screenshots on Failure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload screenshots (selected browser, on failure)&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failure()&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;screenshots-${{ github.event.inputs.browser }}&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cypress/screenshots&lt;/span&gt;
    &lt;span class="na"&gt;if-no-files-found&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step runs only if the job fails.&lt;/p&gt;

&lt;h4&gt;
  
  
  What it does
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Uploads Cypress screenshots as workflow artifacts&lt;/li&gt;
&lt;li&gt;Names the artifact based on the selected browser&lt;/li&gt;
&lt;li&gt;Avoids failing the workflow if no screenshots exist&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;When an E2E test fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screenshots provide visual context&lt;/li&gt;
&lt;li&gt;Browser-specific issues are easier to diagnose&lt;/li&gt;
&lt;li&gt;Artifacts are preserved for later analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This workflow demonstrates a clean and scalable way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manually trigger Cypress tests&lt;/li&gt;
&lt;li&gt;Select the target browser at runtime&lt;/li&gt;
&lt;li&gt;Handle browser-specific dependencies&lt;/li&gt;
&lt;li&gt;Collect meaningful artifacts on failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a powerful pattern for teams that care about cross-browser confidence without overloading their CI pipelines with unnecessary runs.&lt;/p&gt;

&lt;p&gt;More than just automation, this approach puts control and observability back in the team's hands—exactly where quality belongs.&lt;/p&gt;




&lt;p&gt;For the complete implementation, take a look at the &lt;a href="https://github.com/wlsf82/cross-browser-testing-gha" rel="noopener noreferrer"&gt;cross-browser-testing-gha&lt;/a&gt; GitHub repository.&lt;/p&gt;




&lt;p&gt;Would you like to learn E2E Testing with Cypress from scratch until your tests are running on GitHub Actions and integrated with the Cypress Cloud?&lt;/p&gt;

&lt;p&gt;Consider subscribing to my course: "&lt;a href="https://www.udemy.com/course/cypress-from-zero-to-the-cloud/?referralCode=CABCDDFA5ADBB7BE2E1A" rel="noopener noreferrer"&gt;Cypress, from Zero to the Cloud&lt;/a&gt;."&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cicd</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Software Engineering Principles and Ethics</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Tue, 09 Dec 2025 22:31:44 +0000</pubDate>
      <link>https://forem.com/talking-about-testing/software-engineering-principles-and-ethics-3pge</link>
      <guid>https://forem.com/talking-about-testing/software-engineering-principles-and-ethics-3pge</guid>
      <description>&lt;h2&gt;
  
  
  What are the principles that any professional software engineer should comply with?
&lt;/h2&gt;

&lt;p&gt;That’s the question I will try to answer in this blog post.&lt;/p&gt;

&lt;p&gt;But first, let me tell you a story.&lt;/p&gt;

&lt;p&gt;Once upon a time, there was a small team working on a critical application. The deadline was tight, and management was pushing for a release “as soon as possible.” One of the engineers hesitated: some of the automated tests were failing — minor edge cases, nothing too urgent, they argued. “We’ll fix them later,” they said. The pressure to deliver trumped the red test suite. The code was shipped. In production, the very edge cases that those failing tests covered caused a subtle bug that corrupted user data. It took weeks to identify and resolve the issue, which cost the company significant reputational damage and eroded user trust. Ultimately, the “minor” failing tests cost far more than the extra time needed to get them green.&lt;/p&gt;

&lt;p&gt;That engineer’s hesitation — and ultimately the team’s decision to ship with failing tests — was not just a matter of expediency. It was a failure of professional ethics.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why accepting red or failing tests is unethical
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;professional software engineer&lt;/strong&gt; does more than “just write code.” According to Robert C. Martin (often referred to as “Uncle Bob”), programming is an act of responsibility, and professionals must take full ownership of the consequences of their work. In &lt;em&gt;The Clean Coder&lt;/em&gt;, he makes it clear that professionalism is not about compliance, but about ethics: doing the right thing even when it is uncomfortable.&lt;/p&gt;

&lt;p&gt;Accepting a failing test — even “just for now” — violates that responsibility. It knowingly delivers sub-par or unsafe software, relying on the hope that the missing fix will come “later.” That violates the very core of professionalism, because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It destroys the guarantee that the code works as expected. Martin strongly argues that professionals must be confident about all the code they release, and that tests are the foundation of that confidence.&lt;/li&gt;
&lt;li&gt;It erodes trust — among team members, between engineers and stakeholders, and between software and its users. By shipping with red tests, you implicitly communicate that quality is negotiable. That is not what a professional does.&lt;/li&gt;
&lt;li&gt;It encourages a dangerous culture of “debt by default,” where shortcuts become acceptable and technical debt silently becomes the norm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you accept failing tests, you are not just betting on luck — you are betraying the craft.&lt;/p&gt;




&lt;h2&gt;
  
  
  What other thought leaders say about responsibility
&lt;/h2&gt;

&lt;p&gt;This ethical stance is not unique to one author.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kent Beck&lt;/strong&gt;, the creator of Extreme Programming, placed “Respect” at the core of XP. Respect for your teammates means never checking in code that breaks the build or leaves tests failing. If your changes cause others pain, you are not acting professionally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Martin Fowler&lt;/strong&gt; has consistently argued that working software is not enough if the internal quality of the system is decaying. He emphasizes that design and refactoring are continuous responsibilities — not something to postpone indefinitely in favor of “temporary” defects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;John Ousterhout&lt;/strong&gt;, in &lt;em&gt;A Philosophy of Software Design&lt;/em&gt;, strongly warns against “tactical programming,” where engineers optimize for speed today and leave complexity and fragility behind for tomorrow. He argues that real engineering is strategic: reducing complexity over time and refusing to accept unstable or fragile systems.&lt;/p&gt;

&lt;p&gt;These authors approach the topic from different angles, but they converge on the same principle: professionals think long-term rather than short-term.&lt;/p&gt;




&lt;h2&gt;
  
  
  A non-negotiable rule for professionals: never accept red tests
&lt;/h2&gt;

&lt;p&gt;Based on both ethics and practice, there is a rule that should be treated as non-negotiable:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A professional software engineer must never accept or ship code with failing (red) tests — under any circumstances.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Red tests are a signal of broken promises. They tell you the system is not behaving as expected. To ignore that signal is to normalize dishonesty in your own work.&lt;/p&gt;

&lt;p&gt;Robert C. Martin describes professionalism as the courage to say “no” — even to managers — when quality is at risk. Refusing to ship with broken tests is not stubbornness; it is ethical courage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ethics in software engineering is real
&lt;/h2&gt;

&lt;p&gt;Software increasingly controls critical aspects of our lives: money, health, safety, communication, transportation, and many other domains. The idea that it is “okay for now” to ship broken software is not just naive — it is dangerous.&lt;/p&gt;

&lt;p&gt;Accepting failing tests teaches teams to accept uncertainty as normal. It teaches them to postpone discipline. It teaches them to gamble with other people’s safety.&lt;/p&gt;

&lt;p&gt;That is not engineering.&lt;br&gt;
That is not craftsmanship.&lt;br&gt;
That is not professionalism.&lt;/p&gt;




&lt;h2&gt;
  
  
  Professionalism is a daily choice
&lt;/h2&gt;

&lt;p&gt;Professional software engineering is not about being brilliant. It is about being disciplined.&lt;/p&gt;

&lt;p&gt;It is about refusing to lower the bar, even when deadlines are tight.&lt;br&gt;
It is about refusing to normalize brokenness.&lt;br&gt;
It is about choosing integrity over convenience.&lt;/p&gt;

&lt;p&gt;If you want to call yourself a professional, then this is the standard:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never accept red tests.&lt;br&gt;&lt;br&gt;
Never ship with red tests.&lt;br&gt;&lt;br&gt;
Never normalize brokenness.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Demand green tests. Ship only with green tests. Do it always.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>ethics</category>
      <category>professionalism</category>
      <category>softwarecraftsmanship</category>
    </item>
    <item>
      <title>Uma hipótese para os layoffs do Itaú</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Sun, 05 Oct 2025 15:04:29 +0000</pubDate>
      <link>https://forem.com/talking-about-testing/uma-hipotese-para-os-layoffs-do-itau-304f</link>
      <guid>https://forem.com/talking-about-testing/uma-hipotese-para-os-layoffs-do-itau-304f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Isenção de responsabilidade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As ideias expressas neste texto são apenas hipóteses, discutidas com o intuito de analisar um acontecimento por outro ponto de vista, não discutido em outras publicações sobre o mesmo acontecimento.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setembro de 2025
&lt;/h2&gt;

&lt;p&gt;Nos últimos dias, tenho visto uma enxurrada de publicações no LinkedIn sobre os recentes &lt;em&gt;layoffs&lt;/em&gt; do Itaú, estimados em aproximadamente mil pessoas afetadas.&lt;/p&gt;

&lt;p&gt;Os motivos sugerem falta de produtividade de profissionais trabalhando na modalidade remota, na qual, como uma das medidas, usava-se monitoramento de atividades nos computadores da empresa.&lt;/p&gt;

&lt;p&gt;No entanto, outro possível motivo seria o seguinte.&lt;/p&gt;

&lt;p&gt;O Itaú é uma empresa listada na bolsa de valores (BOVESPA).&lt;/p&gt;

&lt;p&gt;Ações de empresas listadas em bolsa valorizam (ou desvalorizam), dentre outras coisas, devido ao seu resultado financeiro.&lt;/p&gt;

&lt;p&gt;O Itaú já entrega ótimos resultados financeiros aos seus acionistas. Ainda assim, pessoas ainda são um dos maiores custos da maioria dos negócios, e uma forma de melhorar o resultado financeiro de uma empresa (seja ela listada ou não) é o corte de custos.&lt;/p&gt;

&lt;p&gt;Façamos uma "conta de padeiro" pra você ter idéia de quanto dinheiro pode-se tratar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Os valores usados abaixo são totalmente hipotéticos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine um funcionário que ganha em média R$5.000,00 (cinco mil reais) brutos mensais.&lt;/p&gt;

&lt;p&gt;E digamos que para a empresa, o funcionário custa o dobro, ou seja, R$10.000 (dez mil reais) mensais.&lt;/p&gt;

&lt;p&gt;Ou seja, em 13 meses (12 meses trabalhados + o décimo terceiro), tal funcionário custaria aproximadamente R$130.000 (cento e trinta mil reais).&lt;/p&gt;

&lt;p&gt;E visto que a estimativa é de mil pessoas afetadas, o banco teria uma redução de custos de aproximadamente 130.000.000 (cento e trinta milhões de reais).&lt;/p&gt;

&lt;p&gt;Não sei pra você, mas pra mim, isso é muito dinheiro.&lt;/p&gt;

&lt;p&gt;Um parêntesis.&lt;/p&gt;

&lt;p&gt;(E se algumas das pessoas afetadas pelos &lt;em&gt;layoffs&lt;/em&gt; realmente não entregavam a produtividade esperada?&lt;/p&gt;

&lt;p&gt;Neste caso, a empresa ganha duas vezes. Uma, pois "elimina" pessoas não produtivas, as quais podem ser futuramente substituídas, ou por pessoas mais produtivas, ou até mesmo por agentes de IA e outras tecnologias. E dois, pois não tem mais este custo afetando seu resultado financeiro, podendo elevar ainda mais o preço de suas ações.)&lt;/p&gt;

&lt;p&gt;Fecha parêntesis.&lt;/p&gt;

&lt;p&gt;Não quero entrar no mérito de se o que ocorreu é certo ou errado. Até mesmo, pois acredito que &lt;strong&gt;não&lt;/strong&gt; temos que romantizar relações de trabalho. Sua empresa não é sua mãe, nem seu pai, portanto, temos que estar preparados para que tal relação acabe (seja por decisão da empresa, como por sua escolha própria).&lt;/p&gt;

&lt;p&gt;Como escrevi no título, esta é só uma hipótese. E escrevi esta hipótese para instigar o pensamento sob outra perspectiva, mesmo que a hipótese esteja errada.&lt;/p&gt;

&lt;p&gt;Eu imagino que algumas pessoas perderam seus empregos, quem sabe, de forma injusta. Mas é do jogo.&lt;/p&gt;

&lt;p&gt;Minha dica é: bola pra frente! E prepare-se para o pior, pois essa é a melhor forma de uma situação como essa não te afetar tanto no futuro.&lt;/p&gt;

&lt;p&gt;Obrigado por ler até aqui.&lt;/p&gt;

&lt;p&gt;E aí, gostou? Continue essa conversa deixando um comentário.&lt;/p&gt;

&lt;p&gt;E por favor, seja educado(a), seja lá se você concorda ou não com o que escrevi, pois a intenção é simplesmente levantar uma possibilidade, não ser uma verdade absoluta.&lt;/p&gt;

&lt;p&gt;E aos/às afetados/as pelo &lt;em&gt;layoff&lt;/em&gt;, boa sorte no que vem por aí. E lembre-se, "a males que vem para o bem".&lt;/p&gt;

</description>
      <category>layoffs</category>
      <category>layoff</category>
      <category>itaú</category>
      <category>techcommunity</category>
    </item>
    <item>
      <title>Simulando navegação por teclado com as novas teclas do comando cy.press na versão 15.1.0 do Cypress</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Thu, 04 Sep 2025 00:34:30 +0000</pubDate>
      <link>https://forem.com/talking-about-testing/simulando-navegacao-por-teclado-com-as-novas-teclas-do-comando-cypress-na-versao-1510-do-cypress-1ind</link>
      <guid>https://forem.com/talking-about-testing/simulando-navegacao-por-teclado-com-as-novas-teclas-do-comando-cypress-na-versao-1510-do-cypress-1ind</guid>
      <description>&lt;h2&gt;
  
  
  &lt;code&gt;TAB&lt;/code&gt;, &lt;code&gt;SPACE&lt;/code&gt; e muito mais agora fazem parte da sua estratégia de testes automatizados
&lt;/h2&gt;

&lt;p&gt;A versão 15.1.0, o Cypress introduziu uma melhoria importante para quem testa acessibilidade e navegação por teclado: o comando &lt;a href="https://docs.cypress.io/api/commands/press" rel="noopener noreferrer"&gt;&lt;code&gt;cy.press&lt;/code&gt;&lt;/a&gt; agora suporta novas teclas, como &lt;code&gt;ENTER&lt;/code&gt;, &lt;code&gt;SPACE&lt;/code&gt; e outras, além da tecla &lt;code&gt;TAB&lt;/code&gt; (disponível desde a versão &lt;a href="https://docs.cypress.io/app/references/changelog#14-3-0" rel="noopener noreferrer"&gt;14.3.0&lt;/a&gt;). Essa mudança, destacada no &lt;a href="https://docs.cypress.io/app/references/changelog#15-1-0" rel="noopener noreferrer"&gt;&lt;em&gt;changelog&lt;/em&gt; oficial&lt;/a&gt;, amplia o leque de cenários que conseguimos cobrir com testes &lt;em&gt;end-to-end&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Se antes precisávamos de &lt;em&gt;workarounds&lt;/em&gt; para simular o pressionamento de teclas específicas, ou mesmo de testes manuais, agora podemos testar fluxos completos de interação apenas com o teclado, garantindo que pessoas que dependem dessa forma de navegação também tenham uma boa experiência. E tudo isso de forma automatizada!&lt;/p&gt;

&lt;p&gt;Vejamos um exemplo.&lt;/p&gt;

&lt;h3&gt;
  
  
  O cenário de teste
&lt;/h3&gt;

&lt;p&gt;No exemplo abaixo, criamos um teste que valida a navegação por um &lt;em&gt;messenger&lt;/em&gt; de uma aplicação fictícia, utilizando apenas &lt;code&gt;TAB&lt;/code&gt; para avançar entre os campos e &lt;code&gt;SPACE&lt;/code&gt; para acionar os botões:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para digitar nos campos, utilizamos a conhecido comando &lt;a href="http://on.cypress.io/type" rel="noopener noreferrer"&gt;&lt;code&gt;cy.type()&lt;/code&gt;&lt;/a&gt;, existente desde as primeiras versões do Cypress.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// cypress/e2e/spec.cy.js&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TAB navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Set a cookie before visiting the page to prevent it from showing up&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cookieConsent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accepted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Visit the app&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;table&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press TAB 20 times to reach the open messenger button&lt;/span&gt;
    &lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressTAB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// Make sure the open messenger button is focused&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[aria-label="Open messenger"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Open the messager by pressing SPACE on the focused button&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressSPACE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigates through the messenger using the TAB key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Ensure the messenger opens with its first field pre-focused (i.e., the name field), and types the required info in it&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#messenger-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press TAB to move to the email field&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressTAB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Make sure the email field is focused and type a valid email in it&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;johndoe@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press TAB to move to the message textarea&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressTAB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Make sure the textarea field is focused and type a message in it&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The client with ID 5 has no contact info available.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press TAB to move to the send button&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressTAB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Make sure the button is focused&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press SPACE to submit the form&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressSPACE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Ensure the success message is displayed (which could be read by a screen reader)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your message has been sent.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press TAB to move to the close messenger button&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressTAB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Ensure the closed button is focused&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[aria-label="Close messenger"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.focused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Press SPACE to close the messenger&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressSPACE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Ensure the messenger was closed by checking that the open messenger button is now visible&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[aria-label="Open messenger"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Os comandos customizados
&lt;/h3&gt;

&lt;p&gt;Para simplificar a leitura do teste, criamos dois comandos customizados no arquivo &lt;code&gt;cypress/support/commands.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pressTAB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TAB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pressSPACE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SPACE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esses comandos são carregados automaticamente pelo arquivo &lt;code&gt;cypress/support/e2e.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./commands&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  O que mudou no &lt;code&gt;cy.press&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Antes (entre as versões 14.3.0 e 15.0.0), o suporte era limitado somente a tecla &lt;code&gt;TAB&lt;/code&gt;. Agora, podemos acessar atalhos e teclas especiais como &lt;code&gt;ENTER&lt;/code&gt;, &lt;code&gt;BACKSPACE&lt;/code&gt;, &lt;code&gt;SPACE&lt;/code&gt;, entre outras.&lt;/p&gt;

&lt;p&gt;Isso abre espaço para testes de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Acessibilidade&lt;/strong&gt;: garantir que os elementos da página são alcançáveis por &lt;code&gt;TAB&lt;/code&gt; e ativáveis por &lt;code&gt;SPACE&lt;/code&gt; ou &lt;code&gt;ENTER&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fluxos reais de formulários&lt;/strong&gt;: preencher campos apenas com navegação por teclado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interações avançadas&lt;/strong&gt;: menus suspensos, modais e tooltips acionados por teclas específicas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Com o suporte expandido do comando &lt;a href="https://docs.cypress.io/api/commands/press" rel="noopener noreferrer"&gt;&lt;code&gt;cy.press&lt;/code&gt;&lt;/a&gt;, fica mais simples criar testes que refletem o uso real da aplicação por usuários que dependem de navegação por teclado.&lt;/p&gt;

&lt;p&gt;Essa evolução do Cypress não só melhora a cobertura de testes, mas também reforça o compromisso com experiências inclusivas e acessíveis.&lt;/p&gt;

&lt;p&gt;👉 Confira a documentação oficial do comando &lt;a href="https://docs.cypress.io/api/commands/press" rel="noopener noreferrer"&gt;&lt;code&gt;cy.press&lt;/code&gt;&lt;/a&gt; e explore suas possibilidades para seus próximos testes.&lt;/p&gt;




&lt;p&gt;Quer aprender mais sobre testes de acessibilidade com Cypress? Conheça o curso &lt;a href="https://www.udemy.com/course/cypress-simulator/?referralCode=90B4D45A98C81CF09710" rel="noopener noreferrer"&gt;Cypress Simulator&lt;/a&gt; da &lt;a href="https://talking-about-testing.vercel.app" rel="noopener noreferrer"&gt;Escola Talking About Testing&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>acessibilidade</category>
      <category>testing</category>
      <category>web</category>
    </item>
    <item>
      <title>Cypress v15: A Better User Experience</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Tue, 19 Aug 2025 23:45:47 +0000</pubDate>
      <link>https://forem.com/cypress/cypress-v15-a-better-user-experience-10d3</link>
      <guid>https://forem.com/cypress/cypress-v15-a-better-user-experience-10d3</guid>
      <description>&lt;h2&gt;
  
  
  Streamlined Features and Improvements for Modern Testing
&lt;/h2&gt;

&lt;p&gt;Cypress v15 is just around the corner, and one of the exciting changes is an improved user experience in the command logs of the test runner. If you’ve spent time debugging tests in v14, you’ll immediately notice how v15 makes test execution logs easier to scan, parse, and act upon.&lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through the key UX improvements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At the end of this post, screenshots will illustrate the differences between v14 and v15.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Hierarchical Grouping
&lt;/h3&gt;

&lt;p&gt;In v15, the test log is segmented into clear sections &lt;strong&gt;with borders&lt;/strong&gt; to distinguish between: SESSIONS, BEFORE EACH, and TEST BODY.&lt;br&gt;
In v14, although SESSIONS, BEFORE EACH, and TEST BODY also appear, there's no border to differentiate and isolate them better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cleaner Visual Density
&lt;/h3&gt;

&lt;p&gt;The v15 layout introduces tighter grouping and spacing, so related blocks are easier to scan. The result is less eye travel compared to v14’s list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Cypress v15 isn’t just a version bump—it’s a thoughtful step forward in how developers and testers interact with their test runner. By rethinking the command log experience with hierarchical grouping and cleaner visual density, Cypress reduces cognitive load and makes debugging more intuitive.&lt;/p&gt;

&lt;p&gt;If you’ve ever found yourself lost in the flat logs of v14, v15 will feel like a breath of fresh air. These changes may seem subtle, but they directly improve day-to-day productivity and test clarity. And when it comes to testing, minor UX improvements often translate into big wins for speed, focus, and confidence.&lt;/p&gt;

&lt;p&gt;As Cypress continues to evolve, v15 is a reminder that great tooling isn’t just about raw features—it’s about delivering a user experience that helps teams ship quality software faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Illustrations comparing Cypress versions 14 and 15
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;v14 session collapsed&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1e832m2njts5ha8kil3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1e832m2njts5ha8kil3.png" alt=" " width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v15 session collapsed&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcme21op16sjrtrvat2xv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcme21op16sjrtrvat2xv.png" alt=" " width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v14 session expanded&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F374kwenx8suhjcn0t2dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F374kwenx8suhjcn0t2dv.png" alt=" " width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;v15 session expanded&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66wdms8xx7qu1oag2lka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66wdms8xx7qu1oag2lka.png" alt=" " width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Would you like to learn more about web testing with Cypress?&lt;br&gt;
Check out the "&lt;a href="https://www.udemy.com/course/cypress-from-zero-to-the-cloud/?referralCode=CABCDDFA5ADBB7BE2E1A" rel="noopener noreferrer"&gt;Cypress, from Zero to the Cloud&lt;/a&gt;" course from the Talking About Testing online school, and happy testing!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Uma alternativa de processo seletivo para contratar melhores QAs</title>
      <dc:creator>Talking About Testing</dc:creator>
      <pubDate>Fri, 21 Mar 2025 01:35:54 +0000</pubDate>
      <link>https://forem.com/talking-about-testing/uma-alternativa-de-processo-seletivo-para-contratar-melhores-qas-1n78</link>
      <guid>https://forem.com/talking-about-testing/uma-alternativa-de-processo-seletivo-para-contratar-melhores-qas-1n78</guid>
      <description>&lt;h2&gt;
  
  
  A indústria de qualidade de software está estagnada. Precisamos mudar isso!
&lt;/h2&gt;

&lt;p&gt;Aqui vai um exercício de pensamento.&lt;/p&gt;

&lt;p&gt;Imagine um mundo onde:&lt;/p&gt;

&lt;p&gt;Em vez de você filtrar candidatos(as) por terem (ou não) a certificação CTFL, você os/as filtra por terem (ou não) projetos públicos no GitHub (ou GitLab, etc), os quais podem ser usados para demonstrar suas habilidades.&lt;/p&gt;

&lt;p&gt;Ao usar uma certificação como filtro para eliminar candidatos(as) da participação no processo seletivo, você elimina a chance de empresas conhecerem possíveis &lt;strong&gt;excelentes&lt;/strong&gt; profissionais.&lt;/p&gt;

&lt;p&gt;Imagine uma QA que estudou a literatura recomendada para tal certificação, fez cursos a respeito do assunto, e na hora da prova, não passou. Digamos que a nota mínima para passar era 7.5 e a QA atingiu 7.4.&lt;/p&gt;

&lt;p&gt;Agora, imagine um QA que estudou a mesma literatura, fez os mesmos cursos e passou na prova com a nota 7.6.&lt;/p&gt;

&lt;p&gt;Você segue o processo seletivo com o QA que tirou 7.6 e elimina a QA que atingiu 7.4.&lt;/p&gt;

&lt;p&gt;No entanto, na próxima fase do processo seletivo, você tem um exercício de codificação para analisar se tal QA sabe automatizar testes.&lt;/p&gt;

&lt;p&gt;Tal QA não possui experiência prévia em codificação, pede ajuda pro ChatGPT, entrega algo que ele nem mesmo entende e submete seu exercício para análise.&lt;/p&gt;

&lt;p&gt;Agora, alguém da empresa contratante tem que revisar tal código, que nem mesmo foi criado pela pessoa aplicando para a vaga, mas por uma IA Generativa. Neste caso, não seria melhor contratar o ChatGPT em vez desse QA? :D&lt;/p&gt;

&lt;p&gt;Agora, imagine que você soubesse o seguinte sobre a QA que atingiu 7.4 na prova do CTFL, a qual não conseguiu a certificação.&lt;/p&gt;

&lt;p&gt;Ela possuía vasta experiência prática em garantir a qualidade de diferentes softwares por meio de scripts de testes automatizados de alto-nível.&lt;/p&gt;

&lt;p&gt;Quando digo alto-nível, me refiro a testes automatizados que, além de testarem as partes mais importantes do sistema, também:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usam as melhores práticas do mercado&lt;/li&gt;
&lt;li&gt;Seguem as convenções definidas pela comunidade&lt;/li&gt;
&lt;li&gt;São fáceis de manter, entender e extender&lt;/li&gt;
&lt;li&gt;São rápidos, robustos e confiáveis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora, imagine que seu filtro fosse diferente.&lt;/p&gt;

&lt;p&gt;De agora em diante, seu filtro é: &lt;strong&gt;projetos públicos no GitHub&lt;/strong&gt; (ou qualquer outro lugar onde seja possível compartilhar código publicamente).&lt;/p&gt;

&lt;p&gt;Voltamos aos mesmos QAs.&lt;/p&gt;

&lt;p&gt;O QA que tirou 7.6 na prova da CTFL nem mesmo tem um perfil no GitHub, no entanto, como "campo" perfil no GitHub é um pré-requisito para aplicação para a vaga, o QA cria uma conta na hora e coloca lá o link.&lt;/p&gt;

&lt;p&gt;Ao abrir o link de perfil de tal QA, você não só consegue ver que ele acabou de criar a conta, como não possui nenhum projeto para demonstrar seu conhecimento de forma prática.&lt;/p&gt;

&lt;p&gt;No entanto, a QA tem conta no GitHub desde 2012, tem diversos repositórios públicos, tem uma evolução de commits de ano em ano, e mais importante, tem um histórico de sua evolução, assim como diversos projetos que possam ser avaliados de antemão pelo possível contratante.&lt;/p&gt;

&lt;p&gt;A partir daí, o processo poderia ser algo como o seguinte.&lt;/p&gt;

&lt;p&gt;O QA, foi eliminado.&lt;/p&gt;

&lt;p&gt;Já a QA, passou para a próxima fase.&lt;/p&gt;

&lt;p&gt;Agora, uma pessoa sênior da empresa contratante seleciona 3 projetos públicos aleatórios na conta do GitHub dessa QA, de preferência de momentos distintos de sua carreira (para avaliar sua evolução) e analisa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como ela codifica&lt;/li&gt;
&lt;li&gt;Quão abrangentes e efetivas são suas suítes testes&lt;/li&gt;
&lt;li&gt;Suas habilidades de escrita de documentações&lt;/li&gt;
&lt;li&gt;Etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Passando nesse filtro, ou seja, seguindo os padrões técnicos mínimos exigidos para a vaga, ela passa para a próxima fase, com uma entrevista comportamental/de &lt;em&gt;fit&lt;/em&gt; cultural, e por fim, uma entrevista com alguém da gestão, para alinhamento de expectativas.&lt;/p&gt;

&lt;p&gt;Pergunte-se agora.&lt;/p&gt;

&lt;p&gt;"Qual dessas abordagens parece mais efetiva para seguir adiante (ou eliminar) o/a candidato(a)?"&lt;/p&gt;

&lt;p&gt;Pense antes de responder!&lt;/p&gt;

&lt;p&gt;Venho dizendo isso faz algum tempo, mas vou repetir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A indústria de qualidade software está estagnada. Precisamos mudar isso!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;E pra mudar isso, é preciso re-pensar processos que atrasam nossa indústria.&lt;/p&gt;

&lt;p&gt;Você já parou para pensar em &lt;strong&gt;quanto dinheiro empresas que emitem certificações (e empresa que treinam pessoas para passarem em tais certificações) ganham?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agora, imagine uma pessoa que estudou para a certificação, passaria com 10, mas decidiu não gastar o dinheiro com tal certificação.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O conhecimento que ela adquiriu você não tira dela, independente se ela tem (ou não) a certificação.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ou seja, a certificação não prova nada.&lt;/p&gt;

&lt;p&gt;No entanto, a experiência prática, seja através cursos práticos, contribuições com projetos &lt;em&gt;open-source&lt;/em&gt;, &lt;em&gt;hackathons&lt;/em&gt;, &lt;em&gt;bootcamps&lt;/em&gt;, etc, isso pode ser avaliado (tanto tecnicamente, como subjetivamente).&lt;/p&gt;

&lt;p&gt;Nos dias de hoje, automação de testes é o mínimo esperado de profissionais de QA.&lt;/p&gt;

&lt;p&gt;Fazer trabalho que pode ser automatizado de forma manual é simplesmente um desperdício.&lt;/p&gt;

&lt;p&gt;No entanto, não adianta fazer testes de qualquer jeito.&lt;/p&gt;

&lt;p&gt;Não adianta escrever scripts de testes que passam na primeira vez, mas com o passar do tempo, se mostram frágeis e não-confiáveis.&lt;/p&gt;

&lt;p&gt;Não adianta escrever testes que quando falham, não tem nada errado com a aplicação sendo testada.&lt;/p&gt;

&lt;p&gt;Além disso, não adiante escrever os testes errados, ou seja, testes que apesar de existirem, deixam bugs importantes passarem.&lt;/p&gt;

&lt;p&gt;A tecnologia está toda à nossa disposição.&lt;/p&gt;

&lt;p&gt;Lembre-se! &lt;strong&gt;Escrever &lt;em&gt;scritps&lt;/em&gt; de testes é codificar&lt;/strong&gt;, e se exigimos que times de desenvolvimento escrevam códigos de alta qualidade, por qual motivo não exigimos o mesmo de times de QA?&lt;/p&gt;

&lt;p&gt;Contratamos QAs para encontrarem bugs nas aplicações sendo construídas, mas quem encontra os "bugs" nos scripts de testes escritos por esses/essas QAs?&lt;/p&gt;

&lt;p&gt;Tá na hora de subir a régua!&lt;/p&gt;

&lt;p&gt;Esse papo de "basta conhecer o básico de programação para começar a automatizar" não pode mais ser aceito.&lt;/p&gt;

&lt;p&gt;É simplesmente contraditório contratar pessoas para garantirem a qualidade dos softwares sendo construídos se elas nem mesmo sabem o básico de como softwares são construídos.&lt;/p&gt;

&lt;p&gt;E se você não concorda com o que está lendo, fico feliz que ao menos chegou até aqui. Se não quiser, não precisa mais ler.&lt;/p&gt;

&lt;p&gt;Já se você concorda com essas idéias, continua comigo.&lt;/p&gt;

&lt;p&gt;Ao conhecer com profundidade uma linguagem de programação; ou uma ferramenta; ou um framework de automação de testes, você saberá como fazer bom uso destes para garantir a qualidade dos softwares sendo construídos. Você saberá escrever &lt;a href="https://dev.to/walmyrlimaesilv/test-design-what-everyone-should-know-about-test-automation-b68"&gt;testes com um bom design&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Você vai focar na simplicidade em vez da complexidade.&lt;/p&gt;

&lt;p&gt;Você vai focar na legibilidade do código em vez de somente no princípio &lt;em&gt;DRY (Don't Repeat Yourself)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Você vai focar nas abstrações extremamente necessárias, em vez de abstrações superficiais.&lt;/p&gt;

&lt;p&gt;Você vai se preocupar em testes desacoplados de detalhes de implementação da aplicação em teste.&lt;/p&gt;

&lt;p&gt;Você vai se preocupar em escrever testes rápidos, efetivos e que gerem confiança nos times. Testes que quando estão verdes (passando), a nova versão pode ir pra produção. E que quando estão vermelhos (falhando), é por que um problema real foi encontrado, a tempo de correção, antes de chegar no usuário final.&lt;/p&gt;

&lt;p&gt;Quer aprender como chegar nesse próximo nível?&lt;/p&gt;

&lt;p&gt;Te convido a começar com os cursos de automação de testes da &lt;a href="https://talking-about-testing.vercel.app/" rel="noopener noreferrer"&gt;Escola Talking About Testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Depois, venha participar da &lt;a href="https://talkingabouttesting.com/test-design-masterclass/" rel="noopener noreferrer"&gt;Test Design Masterclass&lt;/a&gt;, uma experiência que oferece benefícios significativos para profissionais que desejam aprimorar suas habilidades em design de software com foco em testes automatizados e aumentar suas senioridades para evoluírem em suas carreiras.&lt;/p&gt;

&lt;p&gt;Ou então, venha fazer uma &lt;a href="https://talkingabouttesting.com/servicos/mentoria-coaching/" rel="noopener noreferrer"&gt;mentoria individual&lt;/a&gt; focada em suas necessidades específicas.&lt;/p&gt;

&lt;p&gt;Gostou desse conteúdo? Me diga o que achou nos comentários.&lt;/p&gt;

&lt;p&gt;👋&lt;/p&gt;

</description>
      <category>qualityassurance</category>
      <category>testing</category>
      <category>softwaredevelopment</category>
      <category>career</category>
    </item>
  </channel>
</rss>
