<?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: Alan Richardson</title>
    <description>The latest articles on Forem by Alan Richardson (@eviltester).</description>
    <link>https://forem.com/eviltester</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%2F16567%2Fc2a5e521-adb3-4f81-8c5c-205fcdf7c7fd.jpg</url>
      <title>Forem: Alan Richardson</title>
      <link>https://forem.com/eviltester</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/eviltester"/>
    <language>en</language>
    <item>
      <title>A Web Testing, Automating and Tooling Masterclass</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Thu, 05 Feb 2026 08:30:00 +0000</pubDate>
      <link>https://forem.com/eviltester/a-web-testing-automating-and-tooling-masterclass-4gbb</link>
      <guid>https://forem.com/eviltester/a-web-testing-automating-and-tooling-masterclass-4gbb</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; We can only test to the level supported by our Ability, and the degree to which we are supported by tooling to Observe, Interrogate and Manipulate the System.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Video
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/bSfgADkdQug"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=bSfgADkdQug" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;00:00 Introduction&lt;/li&gt;
&lt;li&gt;00:26 Application Under Test&lt;/li&gt;
&lt;li&gt;02:51 Live Testing&lt;/li&gt;
&lt;li&gt;03:41 Testing vs Automating&lt;/li&gt;
&lt;li&gt;06:03 Testability vs Automatability&lt;/li&gt;
&lt;li&gt;09:25 Workarounds&lt;/li&gt;
&lt;li&gt;10:55 Technical Knowledge&lt;/li&gt;
&lt;li&gt;15:44 Test Approach - JavaScript&lt;/li&gt;
&lt;li&gt;17:02 Exercise - Test Approach&lt;/li&gt;
&lt;li&gt;17:24 Automated Execution Approach&lt;/li&gt;
&lt;li&gt;18:34 Exercise - Code Review&lt;/li&gt;
&lt;li&gt;20:35 Exercise - Your Project&lt;/li&gt;
&lt;li&gt;20:59 Server Side&lt;/li&gt;
&lt;li&gt;24:20 Exercise - Test Approach - API&lt;/li&gt;
&lt;li&gt;24:52 API Tooling&lt;/li&gt;
&lt;li&gt;29:14 Exercise - API Testing&lt;/li&gt;
&lt;li&gt;29:34 Automating the API&lt;/li&gt;
&lt;li&gt;31:54 API Interacting with UI&lt;/li&gt;
&lt;li&gt;37:09 End Notes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A customer has reported that one of your pages doesn’t work. But your automated execution coverage tells you that it does. What went wrong?&lt;/p&gt;

&lt;p&gt;That’s what we’re going to explore now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;difference between testing and automating,&lt;/li&gt;
&lt;li&gt;testability vs automatability,&lt;/li&gt;
&lt;li&gt;we’ll think about test coverage from a technology perspective,&lt;/li&gt;
&lt;li&gt;and we’ll look at some tools that can help you test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the Application Under Test.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infinite Scroll Challenge on the TestPages&lt;/p&gt;

&lt;p&gt;Many sites have infinite scroll. You scroll to the bottom and it loads new items.&lt;/p&gt;

&lt;p&gt;That functionality works. We have have automated coverage. That passes.&lt;/p&gt;

&lt;p&gt;What’s the issue?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Oh yeah, sorry I forgot to mention. I’m going to encourage you to think. Ideally we would do this as a workshop, as hands on training, but it’s a video and text workbook.So all I can do is prompt you into thinking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.eviltester.com/page/contact/" rel="noopener noreferrer"&gt;Contact me&lt;/a&gt; if you are interested in live training for your team or organization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what’s the issue?&lt;/p&gt;

&lt;p&gt;Well, I can’t click the button. The page refreshes and scrolls too quickly and the button isn’t enabled for long enough when it is visible.&lt;/p&gt;

&lt;p&gt;This happens with a lot of infinite scroll sites, there are footers that can’t be clicked, stuff at the bottom of the screen that you can’t see.&lt;/p&gt;

&lt;p&gt;This did work at some point, because we tested it, but I guess someone changed the time out value and the automated execution assertions didn’t flag this as an issue.&lt;/p&gt;

&lt;p&gt;So let’s start thinking about this from a Testing perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live
&lt;/h2&gt;

&lt;p&gt;If this was a live project we could just stop here and raise a defect.&lt;/p&gt;

&lt;p&gt;Obviously the timeout is wrong. Raise the defect. Move on to the next issue.&lt;/p&gt;

&lt;p&gt;But wait.&lt;/p&gt;

&lt;p&gt;We have automated coverage, and it didn’t highlight this issue.&lt;/p&gt;

&lt;p&gt;We should think about the difference between Testing and Automating.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing vs Automating
&lt;/h2&gt;

&lt;p&gt;Testing is what we do. As humans, we interact with the software and we observe, we build models, we learn, we compare the actual interaction with the models. We report information derived from the difference between our models and the observations.&lt;/p&gt;

&lt;p&gt;When we investigate an issue and expand our models we interrogate the system more deeply to learn what’s going on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing is the human activity of interacting, observing, thinking, learning, experimenting.&lt;/li&gt;
&lt;li&gt;Automating, is the human activity of making the interaction and observation of the system an automated process. And that includes the comparing of observed results with the expected results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automating is a human activity which results in the output of an automated execution process. The only involvement with the human after the activity has been automated is to investigate the failure reports and maintain it when it fails.&lt;/p&gt;

&lt;p&gt;So both Automating and Testing are human processes. But testing leads to more human processes, automating leads to an automated process that only involves humans when it fails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; AI might change how I view the process of automating. Certainly I’ll need more distinctions in how I describe nuances around Automating, but for now, all the automating I do is Human Initiated, or Directed, and results in some automated execution process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Testability vs Automatability
&lt;/h2&gt;

&lt;p&gt;And let’s just quickly look at Testability and Automatability because these words are used badly when describing software.&lt;/p&gt;

&lt;p&gt;Is this system testable?&lt;/p&gt;

&lt;p&gt;Yes. I can access it in the browser, I can see it, I can interact with it. The button toggles too quickly but I can test the application.&lt;/p&gt;

&lt;p&gt;But when we talk about testability we often talk about, adding &lt;code&gt;id&lt;/code&gt;s to the elements, make it it more observable, etc.&lt;/p&gt;

&lt;p&gt;Well the &lt;code&gt;id&lt;/code&gt;s, are really for automatability, not testability.&lt;/p&gt;

&lt;p&gt;In the browser, the browser tooling makes it observable because of the technology used, not the system.&lt;/p&gt;

&lt;p&gt;Most of the time when we are talking about testability we are really talking about automatability.&lt;/p&gt;

&lt;p&gt;This application has been built with automatability in mind.&lt;/p&gt;

&lt;p&gt;It has &lt;code&gt;id&lt;/code&gt;s, there are classes, the JavaScript source is visible, it is easy to change the state and configuration variables, this thing is so easy to automate and observe. But none of that was required to help me test it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testability is not the same as automatability.&lt;/strong&gt; Keep that in mind as we continue through this process, particularly when we move to the server side interaction.&lt;/p&gt;

&lt;p&gt;With the JavaScript Infinite Scroll system, the main thing that impacts my Testability, is the bug, preventing me from testing the button functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workarounds
&lt;/h2&gt;

&lt;p&gt;Let’s quickly consider workarounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your ability to find workarounds will impact your ability to test the system.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So your ability impacts the Testability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testability is as much about your ability to test the application as it is the application supporting you in testing it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Depending on how deep you want to go. You can only test the application to the limit that you can observe, manipulate and interrogate the application.&lt;/p&gt;

&lt;p&gt;Your ability to test the application is often impacted by the usability of the application, and that is true here. The application is not usable for one main function so it is hard to test that function.&lt;/p&gt;

&lt;p&gt;But, we can work around that, for this application, with more Technical Knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Knowledge
&lt;/h2&gt;

&lt;p&gt;When working with the web, we need to understand our tool capabilities.&lt;/p&gt;

&lt;p&gt;My tool at this point is the browser.&lt;/p&gt;

&lt;p&gt;What can I do with it?&lt;/p&gt;

&lt;p&gt;I can view the page source.&lt;/p&gt;

&lt;p&gt;I need to be able to understand HTML. Some CSS. Some JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Having the tooling ability to look at the source doesn’t help me unless I understand what I’m looking at.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So if you’re testing web applications, you probably want to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How a browser works,&lt;/li&gt;
&lt;li&gt;How HTML works,&lt;/li&gt;
&lt;li&gt;What is CSS and how we use it,&lt;/li&gt;
&lt;li&gt;What is JavaScript and how it works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the very least to have a reading ability of these technology artifacts.&lt;/p&gt;

&lt;p&gt;So at this level, at the source, with the technical knowledge I have… I can see in the JavaScript some variables, I can see they are amendable.&lt;/p&gt;

&lt;p&gt;But, I don’t have the tooling to amend it yet.&lt;/p&gt;

&lt;p&gt;So, what else do I have available?&lt;/p&gt;

&lt;p&gt;I can look at the dev tools.&lt;/p&gt;

&lt;p&gt;I can see the DOM view shows me much the same as the source. But… it can be different.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The source is what we gave the browser to work with.&lt;/li&gt;
&lt;li&gt;The DOM is what the browser created after interpreting and executing the source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the DOM I can see the JavaScript as well.&lt;/p&gt;

&lt;p&gt;I also have the ability now, to interact and manipulate the JavaScript variables that I observed in the source.&lt;/p&gt;

&lt;p&gt;There are a few timeout and millisecond variables there.&lt;/p&gt;

&lt;p&gt;Perhaps the bug is the &lt;code&gt;scrollAfterMillis&lt;/code&gt; variable?&lt;/p&gt;

&lt;p&gt;Let me change that to &lt;code&gt;3000&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scrollAfterMillis

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And… now it just takes longer to refresh, but I still can’t click the button.&lt;/p&gt;

&lt;p&gt;Let me try the &lt;code&gt;preLoadTimeout&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preLoadTimeout=2000

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the button stays active for 2 seconds before it loads the next set of data. That’s my workaround to make this application testable.&lt;/p&gt;

&lt;p&gt;It also means that I can go a little deeper in the bug report and say that the root cause is the &lt;code&gt;preLoadTimeout&lt;/code&gt; being too small a value so the user doesn’t have time to click the button.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You might be interested in this &lt;a href="https://www.eviltester.com/blog/eviltester/technical_testing/2022-09-22-chrome-dev-tools-overview/" rel="noopener noreferrer"&gt;video and blog post covering more details of Chrome Dev Tools for Testing&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Test Approach
&lt;/h2&gt;

&lt;p&gt;So what is my test approach for this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load the page&lt;/li&gt;
&lt;li&gt;scroll down&lt;/li&gt;
&lt;li&gt;see that it refreshes and adds the data I expect&lt;/li&gt;
&lt;li&gt;click the button&lt;/li&gt;
&lt;li&gt;see that it doesn’t refresh when I scroll&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is that it?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I need to reload the page and check that it starts auto refreshing again?&lt;/li&gt;
&lt;li&gt;How long do I need to wait after stopping it, and trying to scroll to make sure it doesn’t start auto-refreshing again?&lt;/li&gt;
&lt;li&gt;What else?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exercise - What is your test approach?
&lt;/h3&gt;

&lt;p&gt;After this video I encourage you to think through what your Test Approach for this application would be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Approach vs Automated Execution Approach
&lt;/h2&gt;

&lt;p&gt;Once you’ve figure out how to test it, how would you automate it?&lt;/p&gt;

&lt;p&gt;I’ll show you what we have here.&lt;/p&gt;

&lt;p&gt;And this test passes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test  
public void scrollToStopLoadingAndClick(){  
WebDriverWait(driver, Duration.ofSeconds(10)).until(  
        ExpectedConditions.elementToBeClickable(page.getStopLoadingButton()  
    ));  

    page.getStopLoadingButton().click();  

    new WebDriverWait(driver, Duration.ofSeconds(10)).until(  
        ExpectedConditions.textToBePresentInElement(  
            driver.findElement(By.id("statusMessage")),"Clicked")  
    );  
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is that good enough?&lt;/p&gt;

&lt;p&gt;It works. It passes.&lt;/p&gt;

&lt;p&gt;But it didn’t highlight the fact that the halting functionality is unusable for a human.&lt;/p&gt;

&lt;p&gt;This is one of the issues when we automate something.&lt;/p&gt;

&lt;p&gt;We automate the functionality.&lt;/p&gt;

&lt;p&gt;We don’t automate the experience.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are interested in more details about WebDriver with Java then have a look at this &lt;a href="https://testpages.eviltester.com/reference/automating/webdriver/webdriver-java/" rel="noopener noreferrer"&gt;video Masterclass on the basics of WebDriver with Java&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Exercise - Critique the code
&lt;/h3&gt;

&lt;p&gt;So after the video, or now, pause the video.&lt;/p&gt;

&lt;p&gt;Critique this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand what it does&lt;/li&gt;
&lt;li&gt;What does it not do?

&lt;ul&gt;
&lt;li&gt;I can see it doesn’t try to re-scroll the page to make sure that clicking the button stopped the auto-scroll.&lt;/li&gt;
&lt;li&gt;What else does it not do?&lt;/li&gt;
&lt;li&gt;What conditions does it not check?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Should it match the user experience?

&lt;ul&gt;
&lt;li&gt;How could it?&lt;/li&gt;
&lt;li&gt;What would you change to match the user experience?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Much automated execution coverage does not match the user experience. When it doesn’t then there is a risk that the automated execution passes, but the user experience doesn’t.&lt;/p&gt;

&lt;p&gt;And there is a risk we don’t notice.&lt;/p&gt;

&lt;p&gt;Testing will hopefully identify those issues. But automated execution often does not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercise - Consider Your Project
&lt;/h3&gt;

&lt;p&gt;Is there a risk on the projects you work with that the automated execution covers the functionality, but not the user experience of that functionality?&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Side
&lt;/h2&gt;

&lt;p&gt;OK, so that was the JavaScript version of the Infinite Scroll.&lt;/p&gt;

&lt;p&gt;It offered us some scope for thinking like the tester.&lt;/p&gt;

&lt;p&gt;But let’s push this a little further.&lt;/p&gt;

&lt;p&gt;We also have the server side infinite scroll.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/server-side/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/server-side/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It looks the same. It has the same bug, the button is too fast. And my automated execution passes.&lt;/p&gt;

&lt;p&gt;But this page, when it needs new items to display it calls the server to get the information back.&lt;/p&gt;

&lt;p&gt;Do you trust that statement?&lt;/p&gt;

&lt;p&gt;How do you know it calls the server?&lt;/p&gt;

&lt;p&gt;Visibly, in the browser, when I test it and observe the output. It looks the same.&lt;/p&gt;

&lt;p&gt;We need to be able to be able to interact with the application from a technical perspective.&lt;/p&gt;

&lt;p&gt;What if I just think it is connecting to the server, but I accidentally release the wrong version? What if I just renamed the file?&lt;/p&gt;

&lt;p&gt;So we need to check.&lt;/p&gt;

&lt;p&gt;We need to observe the application at multiple technical levels.&lt;/p&gt;

&lt;p&gt;So let’s look in the dev tools again. And this time we’ll look in the network tab.&lt;/p&gt;

&lt;p&gt;Filter by &lt;code&gt;Fetch/XHR&lt;/code&gt; to see the requests made by JavaScript and I can observe a call to &lt;code&gt;moreitems&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s interrogate that request&lt;/p&gt;

&lt;p&gt;I can see a JSON response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {
        "id": 1,
        "text": "This is content item number 1. Scroll down
         to automatically load more content when the
          \"Click to Stop\" button becomes visible."
    },
    {
        "id": 2,
        "text": "This is content item number 2. Scroll down
         to automatically load more content when the
          \"Click to Stop\" button becomes visible."
    },
    ...
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great.&lt;/p&gt;

&lt;p&gt;So I have tooling to increase my ability to test this.&lt;/p&gt;

&lt;p&gt;But I need to know about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP Requests&lt;/li&gt;
&lt;li&gt;Fetch and XML Http Request&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My ability to test this application will be limited if I do not have that technical knowledge and if I do not know how to use the Dev tools network tab.&lt;/p&gt;

&lt;p&gt;But at least I know now that it is making server requests.&lt;/p&gt;

&lt;p&gt;I didn’t have to trust anyone. I could verify that this was true.&lt;/p&gt;

&lt;p&gt;So now, our testing scope just expanded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercise - Server Side Test Approach
&lt;/h3&gt;

&lt;p&gt;Now, what do you have to test?&lt;/p&gt;

&lt;p&gt;Is it good enough to just test the front end now but scrolling up and down and clicking the button?&lt;/p&gt;

&lt;p&gt;After watching this video, take some time to think through what you want to test to cover the Server Side infinite scroll.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do we also have to test that HTTP call?&lt;/li&gt;
&lt;li&gt;How much do we have to test it?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Server Side Test Tooling
&lt;/h2&gt;

&lt;p&gt;And… do you know how to do that?&lt;/p&gt;

&lt;p&gt;How can you amend the HTTP requests?&lt;/p&gt;

&lt;p&gt;We can do some of that from Chrome.&lt;/p&gt;

&lt;p&gt;I could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copy as cURL&lt;/li&gt;
&lt;li&gt;copy as fetch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;with cURL I can use the command line.&lt;/p&gt;

&lt;p&gt;Or fetch I can amend it in the console.&lt;/p&gt;

&lt;p&gt;I could take the cURL and paste it into an API tool.&lt;/p&gt;

&lt;p&gt;I can do that in Bruno by creating a new request from cURL.&lt;/p&gt;

&lt;p&gt;Or in postman I can paste in the cURL command into the new request.&lt;/p&gt;

&lt;p&gt;I can experiment with it in these tools.&lt;/p&gt;

&lt;p&gt;It is important to test the API on its own.&lt;/p&gt;

&lt;p&gt;For example, when I built this, it was only when I was automating and testing the API, that I realised that I really need a limit on the count. If I let people make a request and ask for 6 million items back. That could easily bring down my server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: you can find &lt;a href="https://apichallenges.eviltester.com/tools/clients" rel="noopener noreferrer"&gt;a list of API Tools on the API Challenges site&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Exercise - API Testing
&lt;/h3&gt;

&lt;p&gt;As an exercise, think through what conditions you would want to test on the API, then you can use any of the tooling approaches mentioned to experiment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating The API
&lt;/h2&gt;

&lt;p&gt;I would probably want to automate the API as well.&lt;/p&gt;

&lt;p&gt;This does remove us from the user experience because the responses from this API are normally handled by the UI, so just because we see something working in the API we can’t assume that it works with the API interacting with the UI.&lt;/p&gt;

&lt;p&gt;I used RestAssured to automate the API.&lt;/p&gt;

&lt;p&gt;The coverage runs at the same time as the web UI coverage.&lt;/p&gt;

&lt;p&gt;And I have a lot more coverage at the API level, than I do at the UI level.&lt;/p&gt;

&lt;p&gt;Think about what coverage you would add for the API.&lt;/p&gt;

&lt;p&gt;Then try to automate it. I used Java, with RestAssured, but you could use any library or programming language you want.&lt;/p&gt;

&lt;p&gt;Or you could even have a set of canned requests in Postman or Bruno or any of the other API tools.&lt;/p&gt;

&lt;p&gt;For production API automating, I primarily use code and HTTP or API libraries. I don’t tend to use tools like Bruno or Postman.&lt;/p&gt;

&lt;p&gt;But for production API Testing, I do use Bruno and other tools. Because I like the flexibility and the ability to see the requests being made.&lt;/p&gt;

&lt;p&gt;Testing and Automating often sound like the same thing. But they have different aims and are supported by different tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Interacting with UI
&lt;/h2&gt;

&lt;p&gt;And now I’m in the position where I’m testing the API in isolation of the UI.&lt;/p&gt;

&lt;p&gt;Is that a risk?&lt;/p&gt;

&lt;p&gt;For example, I don’t know how the front end handles a 500 error response. I can see it is the same JSON format but it is a different status code, does that make a difference?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {
        "id"=0,
        "text"="For input string: '-1.02'"
    }
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would you test that?&lt;/p&gt;

&lt;p&gt;Do you know how to test that?&lt;/p&gt;

&lt;p&gt;One way to do that is to use a Proxy.&lt;/p&gt;

&lt;p&gt;Intercept the request, amend it to be one that triggers an error and play it through to the front end.&lt;/p&gt;

&lt;p&gt;And then I can see if the system handles error responses or not.&lt;/p&gt;

&lt;p&gt;I would either use Zap or BurpSuite.&lt;/p&gt;

&lt;p&gt;For this exercise I would use ZAP.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open a session using Edge&lt;/li&gt;
&lt;li&gt;create a new context for testpages.eviltester.com&lt;/li&gt;
&lt;li&gt;filter the history to “Show only URLs in Scope”&lt;/li&gt;
&lt;li&gt;Set the breakpoint on all requests and responses&lt;/li&gt;
&lt;li&gt;trigger a scroll through the UI&lt;/li&gt;
&lt;li&gt;amend the request&lt;/li&gt;
&lt;li&gt;see the result in the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I can use tooling to increase my ability to observe the system and manipulate the system at different technology levels.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: A &lt;a href="https://apichallenges.eviltester.com/tools/proxies" rel="noopener noreferrer"&gt;list of recommended HTTP Proxy Tools is available on the API Challenges site&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  End Notes
&lt;/h2&gt;

&lt;p&gt;It is often surprising how much depth we have to test and automate when testing even simple pieces of functionality.&lt;/p&gt;

&lt;p&gt;The more that we extend our technical ability to cover the multiple levels of the application, and we learn how to use tooling to help us observe, interrogate and manipulate at those different technology levels, the more we can expand the coverage of our testing.&lt;/p&gt;

&lt;p&gt;Automating is not the same as Testing. Both are human processes, but the output of automating is not the same as the output of testing.&lt;/p&gt;

&lt;p&gt;But yes… we can be testing, as we are automating, we may well learn things during the process of automating the application. But we should not confuse the continued execution of the output from automating with testing.&lt;/p&gt;

&lt;p&gt;Testing can miss things because we are human, or we may not have covered the conditions, or we may not have gone deep enough into the system.&lt;/p&gt;

&lt;p&gt;Automated execution can miss things because we humans forgot to add the conditions, or we didn’t assert enough. But automated execution can also miss the human user experience and tell us things are working, when they clearly are not.&lt;/p&gt;

&lt;p&gt;I hope that you do now go off and do the exercises yourself. You may not have all the skills to do this yet, you may not have tried all the tools. That just means you can revisit this exercise and application multiple times as you grow your knowledge and skill set. And repeat it when you want to evaluate or learn new tools.&lt;/p&gt;

&lt;p&gt;That’s why I created the Test Pages, and that’s also why this is a fairly high level overview.&lt;/p&gt;

&lt;p&gt;Remember to work through the exercises.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Applications Under Test
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/server-side/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/challenges/synchronization/infinite-scroll/server-side/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exercise - What is your test approach for JavaScript Infinite Scroll?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;think through what your Test Approach for the JavaScript Infinite Scroll application would be.&lt;/li&gt;
&lt;li&gt;Do you need to reload the page and check that it starts auto refreshing again?&lt;/li&gt;
&lt;li&gt;How long do you need to wait after stopping it, and trying to scroll to make sure it doesn’t start auto-refreshing again?&lt;/li&gt;
&lt;li&gt;What else?

&lt;ul&gt;
&lt;li&gt;what conditions would you cover?&lt;/li&gt;
&lt;li&gt;how would you approach the testing?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exercise - Critique the code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Understand what it does&lt;/li&gt;
&lt;li&gt;What does it not do?     - I can see it doesn’t try to re-scroll the page to make sure that clicking the button stopped the auto-scroll.     - What else does it not do?     - What conditions does it not check?&lt;/li&gt;
&lt;li&gt;Should it match the user experience?     - How could it?     - What would you change to match the user experience?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Critique this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class InfiniteScrollTest {  

    static WebDriver driver;  
    static InfiniteScrollPage page;  

    @BeforeAll  
    static void setupWebDriver(){  
        driver = DriverFactory.getNew();  
        page = new InfiniteScrollPage(driver);  
    }  

    @BeforeEach  
    public void reload(){  
        page.open();  
    }  

    @Test  
    public void scrollToStopLoadingAndClick(){  
            ExpectedConditions.elementToBeClickable(page.getStopLoadingButton()  
        ));  

        page.getStopLoadingButton().click();  

        new WebDriverWait(driver, Duration.ofSeconds(10)).until(  
            ExpectedConditions.textToBePresentInElement(  
                driver.findElement(By.id("statusMessage")),"Clicked")  
        );  
    }  

    @AfterAll  
    public static void closeDriver(){  
        driver.close();  
    }  

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supporting Abstractions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DriverFactory {  
    public static WebDriver getNew() {  

        WebDriver driver;  
        ChromeOptions options = new ChromeOptions();  
        options.addArguments("--disable-smooth-scrolling");   
        driver = new ChromeDriver(options);   
        return driver;  
    }  
}

public class InfiniteScrollPage {  

    private final WebDriver driver;  

    public InfiniteScrollPage(WebDriver driver) {  
        this.driver = driver;  
    }  

    public void open() {  
        String url = SiteConfig.SITE_DOMAIN +
         "/challenges/synchronization/infinite-scroll/";  
        driver.get(url);  
    }  

    public WebElement getStopLoadingButton() {  
        return driver.findElement(By.id("loadMoreBtn"));  
    }  
}

public class SiteConfig {  

    public static final String SITE_DOMAIN = "https://testpages.eviltester.com";  

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise - Consider Your Project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Is there a risk on the projects you work with, that the automated execution covers the functionality, but not the user experience of that functionality?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because if that’s a risk, you might want to revisit your test approach and your automated execution approach.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How might your approach need to change?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exercise - Server Side Test Approach
&lt;/h3&gt;

&lt;p&gt;What do you have to test now that the Server Side calls are involved?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is it good enough to just test the front end now but scrolling up and down and clicking the button?&lt;/li&gt;
&lt;li&gt;Do we also have to test that HTTP call?&lt;/li&gt;
&lt;li&gt;How much do we have to test it?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Exercise - API Testing
&lt;/h3&gt;

&lt;p&gt;As an exercise, think through what conditions you would want to test on the API, then you can use any of the tooling approaches mentioned to experiment.&lt;/p&gt;

&lt;p&gt;Suggested Tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser Dev Tools - fetch requests in console&lt;/li&gt;
&lt;li&gt;Browser Dev Tools - generate cURL and use from CLI&lt;/li&gt;
&lt;li&gt;Bruno&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://apichallenges.eviltester.com/tools/clients" rel="noopener noreferrer"&gt;A List of API Tools is available on API Challenges site&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exercise - UI and API Interactive Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use a Proxy to allow you to observe and interrogate the traffic from the Web Site to the Internal API backend.&lt;/li&gt;
&lt;li&gt;Amend the Request to trigger an error response and see how the front end handles it.&lt;/li&gt;
&lt;li&gt;Try testing the API from within the proxy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;a href="https://apichallenges.eviltester.com/tools/proxies" rel="noopener noreferrer"&gt;list of recommended HTTP Proxy Tools is available on the API Challenges site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>softwaretesting</category>
      <category>testautomation</category>
    </item>
    <item>
      <title>Test Interaction with HTML form fields</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Thu, 15 Jan 2026 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/test-interaction-with-html-form-fields-jah</link>
      <guid>https://forem.com/eviltester/test-interaction-with-html-form-fields-jah</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; When testing web apps we need to test the interaction between the browser implemented controls and our system. We don’t test the browser.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing HTML Form Fields
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/_MmW3M_r1Ls"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=_MmW3M_r1Ls" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Web Technology
&lt;/h2&gt;

&lt;p&gt;I like to use the term Technical Testing.&lt;/p&gt;

&lt;p&gt;Many people don’t. I think other people view the term as implying that some people are technical and other people are not.&lt;/p&gt;

&lt;p&gt;I use the term to cover “Testing which is informed by Technical knowledge”.&lt;/p&gt;

&lt;p&gt;So if you’re testing a web application, you need to understand web technology, you need technical understanding of how browsers and the web works, otherwise you can’t test it effectively.&lt;/p&gt;

&lt;p&gt;In this video I try to explore some of the reasons why this is important.&lt;/p&gt;

&lt;p&gt;If I’m testing a web application and it has a form, and in the form is a date field which has a date control calendar pop up which lets me set a date.&lt;/p&gt;

&lt;p&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%2Fsn9l1o0kwssdz4zzztlk.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%2Fsn9l1o0kwssdz4zzztlk.png" alt="Calendar control image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What should I test?&lt;/p&gt;

&lt;h3&gt;
  
  
  What should I test?
&lt;/h3&gt;

&lt;p&gt;Should I test that…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the calendar popup works on mobile and every web browser?&lt;/li&gt;
&lt;li&gt;the calendar control works with keyboard?&lt;/li&gt;
&lt;li&gt;the calendar control correctly switches years and months when I click the control buttons?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, no. Not if the HTML looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="datetime-local-input" 
 type="datetime-local" name="datetime-local"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of the complex UI interaction is implemented by the browser.&lt;/p&gt;

&lt;p&gt;All our application does is use an off-the-shelf browser provided control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I not test the functionality?
&lt;/h3&gt;

&lt;p&gt;When we are using off-the-shelf controls like this we have to test the interaction between the control and our application.&lt;/p&gt;

&lt;p&gt;If we added JavaScript event listeners to the control to perform extra validation or functionality then… yes we have to test that.&lt;/p&gt;

&lt;p&gt;If we use the date entered in the control by the user, then we have to test that our application can handle the data supplied by the value of that control.&lt;/p&gt;

&lt;p&gt;If we are not using the date then we should question why we have the control on our application UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn to spot technology risks
&lt;/h3&gt;

&lt;p&gt;I can see from the HTML above that there might be an accessibility risk, because I don’t see any ARIA attributes associated with that control.&lt;/p&gt;

&lt;p&gt;So we might not have configured the control in the page properly to implement all the accessibility requirements we might want.&lt;/p&gt;

&lt;p&gt;If we had created a custom control, or it is specialised React control, then we do want to test it because we just introduced a technology risk that might impact mobile and different browsers. We might also have functional bugs.&lt;/p&gt;

&lt;p&gt;But if we are using built in browser controls we don’t need to test as much functionality related to the control. We need to test the functional interaction with our application and custom code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the Domain Configuration
&lt;/h3&gt;

&lt;p&gt;We shouldn’t spend a long time testing validation messages from custom controls, but if a control has been configured then we need to test that the configuration is correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="password-input" type="password" name="password"
 pattern="^[A-Za-z0-9_]{4,12}$" maxlength="14" required="true"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t need to test that the password control above shows dots instead of letters and hides the input. But I do need to check that the configuration we supplied for the validation pattern and length are correct. And I need to make sure that the password is actually required (because we configured that it is).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: eagle-eyed readers, who have a technical understanding of how the configuration works will probably have spotted a bug in the above configuration. Yes. We should find that bug in our testing. And we know to look for it because we understand that the control has been configured with our application domain rules, and that’s what we are testing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Don’t Trust the Client
&lt;/h3&gt;

&lt;p&gt;The greater the technical understanding we have of the web technology, the less we will trust any data that the server receives.&lt;/p&gt;

&lt;p&gt;We can edit the DOM to bypass domain configuration.&lt;/p&gt;

&lt;p&gt;We can use JavaScript to enter data that bypasses browser validation.&lt;/p&gt;

&lt;p&gt;We can bypass the browser altogether and just communicate directly with the server.&lt;/p&gt;

&lt;p&gt;A greater technical understanding allows us to understand the risks of the technology more effectively&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Web Apps
&lt;/h2&gt;

&lt;p&gt;All of the examples above are from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com" rel="noopener noreferrer"&gt;testpages.eviltester.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also have a guide to testing HTML elements to describe some of the risks and issues that we might have when using or configuring off-the-shelf HTML fields and elements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/reference/input-elements/" rel="noopener noreferrer"&gt;Testing Input Elements - Notes and Exercises&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to learn web technologies when testing web applications.&lt;/p&gt;

&lt;p&gt;I have seen people functionally test the browser implemented controls because they didn’t learn web technologies.&lt;/p&gt;

&lt;p&gt;This means they wasted time, because they didn’t understand the technology they were testing.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>New Version of CounterString Extension</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Sun, 04 Jan 2026 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/new-version-of-counterstring-extension-1ndi</link>
      <guid>https://forem.com/eviltester/new-version-of-counterstring-extension-1ndi</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; Generate CounterStrings, random data from Regex, ranges of data, and strings made by concatenating repeated data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I released a new version of my CounterString generation Chrome Extension with new features and a new UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  CounterString Extension
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/EXytN-CR7nM"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=EXytN-CR7nM" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Source and Download Links
&lt;/h2&gt;

&lt;p&gt;I have a tool page for the CounterString extension with more details.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eviltester.com/page/tools/counterstringjs/" rel="noopener noreferrer"&gt;https://www.eviltester.com/page/tools/counterstringjs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you can find the tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/eviltester/counterstringjs" rel="noopener noreferrer"&gt;source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chromewebstore.google.com/detail/counterstring/keklpkmokeicakpclclkdmclhgkklmbd" rel="noopener noreferrer"&gt;on the chrome store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;I first released the CounterString Extension in 2019 (I think), and at that point it was a simple input field that created a string and added it as a value to the input field.&lt;/p&gt;

&lt;p&gt;Now it can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate CounterStrings&lt;/li&gt;
&lt;li&gt;Configurable length and delimiters&lt;/li&gt;
&lt;li&gt;Generate Random Data From Regex&lt;/li&gt;
&lt;li&gt;Generate Character Ranges&lt;/li&gt;
&lt;li&gt;Repeat text, characters and regex&lt;/li&gt;
&lt;li&gt;Add generated data as value, with input event, to an input field&lt;/li&gt;
&lt;li&gt;Trigger Key events to ’type’ the data with configurable speed&lt;/li&gt;
&lt;li&gt;Binary Chop Calculator for field length exploration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of this was a result of migrating code from my Java Test Tool Hub (which I think I worked on about 12 years ago):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/eviltester/testtoolhub" rel="noopener noreferrer"&gt;https://github.com/eviltester/testtoolhub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the Test Tool Hub I took the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Robot - I had to find a different way of triggering events, but this allows ’typing’ the data into the field rather than just amending the value.&lt;/li&gt;
&lt;li&gt;Increased customization of the CounterStrings&lt;/li&gt;
&lt;li&gt;Ranges of Data&lt;/li&gt;
&lt;li&gt;Repeated Data&lt;/li&gt;
&lt;li&gt;Binary Chop Range Calculation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the Data from Regex was repurposing some code from my &lt;a href="https://anywaydata.com" rel="noopener noreferrer"&gt;AnyWayData.com&lt;/a&gt; test data generator which uses the same JavaScript library to generate data from a Regex - &lt;a href="http://fent.github.io/randexp.js/" rel="noopener noreferrer"&gt;RandExp&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CounterStrings
&lt;/h2&gt;

&lt;p&gt;I wrote about &lt;a href="https://www.eviltester.com/2018/05/counterstring-algorithms" rel="noopener noreferrer"&gt;CounterString Algorithms&lt;/a&gt; in an earlier blog post.&lt;/p&gt;

&lt;p&gt;This extension uses both reverse generation and forward generation.&lt;/p&gt;

&lt;p&gt;I initially learned about CounterStrings from &lt;a href="https://satisfice.com" rel="noopener noreferrer"&gt;James Bach&lt;/a&gt;. James has a tool called &lt;a href="https://www.satisfice.com/download/perlclip" rel="noopener noreferrer"&gt;PerlClip&lt;/a&gt; which is a command line tool to generate data directly into the clipboard. This uses a reverse algorithm where the full string is generated and then reversed to paste into a field.&lt;/p&gt;

&lt;p&gt;A forward algorithm allows ’typing’ the String character by character without generating the full string first.&lt;/p&gt;

&lt;p&gt;While I don’t generate the full String first, I do precompute a Schema which I then follow to generate the String, so it takes about the same processing time, but uses less memory and allows streaming of the result.&lt;/p&gt;

&lt;p&gt;I created a different algorithm this time, which is much simpler to understand, but probably takes longer to execute. I’ll need to update the algorithm page at some point, but you can see the algorithm implemented in the source code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/eviltester/counterstringjs/blob/master/extension/js/generateSchema.js" rel="noopener noreferrer"&gt;github.com/eviltester/counterstringjs/blob/master/extension/js/generateSchema.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other CounterString Tools
&lt;/h2&gt;

&lt;p&gt;A quick hunt around the web revealed a few more CounterString tools that I don’t think I had found all of these before. So these might be interesting for anyone thinking of creating their own implementation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PERL: &lt;a href="https://www.satisfice.com/download/perlclip" rel="noopener noreferrer"&gt;https://www.satisfice.com/download/perlclip&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TYPESCRIPT: &lt;a href="https://github.com/j19sch/counterstring/" rel="noopener noreferrer"&gt;https://github.com/j19sch/counterstring/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RUBY: &lt;a href="https://github.com/jamesmartin/counterstring" rel="noopener noreferrer"&gt;https://github.com/jamesmartin/counterstring&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;JAVA: &lt;a href="https://github.com/eviltester/testtoolhub" rel="noopener noreferrer"&gt;https://github.com/eviltester/testtoolhub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PYTHON: &lt;a href="https://github.com/deefex/pyclip" rel="noopener noreferrer"&gt;https://github.com/deefex/pyclip&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RUST: &lt;a href="https://github.com/thomaschaplin/rust-counter-strings" rel="noopener noreferrer"&gt;https://github.com/thomaschaplin/rust-counter-strings&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another Chrome Extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Pawel-Albert/utilities-for-testing-extension" rel="noopener noreferrer"&gt;https://github.com/Pawel-Albert/utilities-for-testing-extension&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;and some associated Test Pages that I haven’t seen before&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pawel-albert.github.io/utilities-for-testing-extension/" rel="noopener noreferrer"&gt;https://pawel-albert.github.io/utilities-for-testing-extension/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>softwaretesting</category>
      <category>exploratorytesting</category>
    </item>
    <item>
      <title>Software Testing Podcast - AI Optimism or Pessimism - The Evil Tester Show Episode 028</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Thu, 18 Dec 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/software-testing-podcast-ai-optimism-or-pessimism-the-evil-tester-show-episode-028-4jln</link>
      <guid>https://forem.com/eviltester/software-testing-podcast-ai-optimism-or-pessimism-the-evil-tester-show-episode-028-4jln</guid>
      <description>&lt;p&gt;Rather than retrospect on the year in general. This podcasts looks at how I’ve been approaching the learning of AI. Where the industry has gone wrong and what to look forward to with AI.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/GSweziWVfDE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.eviltester.com/show/029-ai-optimism-or-pessimism/" rel="noopener noreferrer"&gt;audio links and subscribe here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Optimism or Pessimism
&lt;/h2&gt;

&lt;p&gt;I sat down to think what am I optimistic about, and what am I pessimistic about with the Software Development industry’s use of AI.&lt;/p&gt;

&lt;p&gt;I see a lot of positive benefits for AI use in the Software Development Process.&lt;/p&gt;

&lt;p&gt;There are many risks involved with adding AI into products and we should rightly be concerned about those and try to identify how to test AI enabled applications properly.&lt;/p&gt;

&lt;p&gt;Many of the statements concerning how Software Testing has to evolve concern me. e.g. more technical skills, more focus on risk, point out flaws in process, identify architecture risk. I thought Software Testing already did this. So perhaps one good thing from AI is an evaluation of what part Software Testing plays in the Development Process and what are the fundamental skills and knowledge we need in order to Test software effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Productivity
&lt;/h2&gt;

&lt;p&gt;I’m incredibly optimistic about what I can personally do with AI. It’s massively increased what I can get done, especially in programming, content creation, and marketing.&lt;/p&gt;

&lt;p&gt;But companies are cutting jobs and blaming AI. But companies have always looked for scapegoats when trimming staff AI is just the latest excuse.&lt;/p&gt;

&lt;p&gt;If leadership truly saw their people as the reason for their growth, they’d use AI to amplify productivity and expand the team’s capabilities, not use it as a reason to shrink down.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If companies viewed the staff as a core engine for growth, they wouldn’t want to get rid of people when AI comes in. They’d want to use AI to make the staff more effective and grow the company. Clearly they don’t.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many management teams see staff as a cost center, not as an engine for growth. Sales gets viewed as the engine of growth and is often paid on commission, so it seems cheap. The product is a ’thing to be sold’. And management… are always essential.&lt;/p&gt;

&lt;p&gt;Some organizations don’t think “how do we help our people do more?” They take the position: “how can we do the same (or less) with fewer people?”&lt;/p&gt;

&lt;p&gt;AI is the scapegoat. Not the cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short-Term Pessimism
&lt;/h2&gt;

&lt;p&gt;AI is overhyped. Leadership decisions are being made based on hope, not the technology’s actual capabilities.&lt;/p&gt;

&lt;p&gt;In the short term, I’m a bit pessimistic, not about AI itself, but about how people (management) are choosing to react to it. Too many seem to want to use AI to restrict and constrain, instead of to grow.&lt;/p&gt;

&lt;p&gt;But our work is already changing. New tools exist. We can’t afford to be complacent. We need to experiment and figure out where AI makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Should We Use AI?
&lt;/h2&gt;

&lt;p&gt;Not every product needs AI enablement and features. Too much risk, particularly if you do not know how to test the results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I do NOT use AI for direct human-to-human communication.

&lt;ul&gt;
&lt;li&gt;If you get an email from me, I wrote it. If I get one from you, I read it, not an AI.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;I would not use AI for company procedures or performance reviews.

&lt;ul&gt;
&lt;li&gt;Adding AI to these human, recognition-based workflows is a mistake.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;I won’t use AI as a buffer between people.

&lt;ul&gt;
&lt;li&gt;Don’t use AI to hide. Engage.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I do use AI to summarize public podcasts, blog posts, etc, Stuff I choose to consume, but not personal, direct communication.&lt;/p&gt;

&lt;p&gt;Management is about people, and putting an AI buffer between you and your team leads to bad communication and alienation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Your boss should already know what you’re doing. They should be helping you explain the value that you’ve added. This is a human process of recognizing value. It’s not something that we add AI into the middle of.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How I learned AI
&lt;/h2&gt;

&lt;p&gt;When I started playing with AI, I created a podcast summarizer. My process for learning anything new is to find a project and use the new technology to build something.&lt;/p&gt;

&lt;p&gt;I wanted to consume more podcasts but couldn’t keep up. So, I wrote a tool using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hugging Face libraries&lt;/li&gt;
&lt;li&gt;Whisper AI for transcription&lt;/li&gt;
&lt;li&gt;Different LLM models for summarization&lt;/li&gt;
&lt;li&gt;Prompt engineering&lt;/li&gt;
&lt;li&gt;Ollama for running models locally&lt;/li&gt;
&lt;li&gt;OpenRouter for connecting to cloud-based models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I did everything locally as much as possible, partly to learn the limits before relying on cloud or paid models. Only after learning the limits did I see real value in some of the paid services.&lt;/p&gt;

&lt;p&gt;Don’t believe in ‘magic’ from big models until you know what smaller, free models can actually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step By Step Adoption
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Chat Interfaces
&lt;/h3&gt;

&lt;p&gt;At first, I used AI the same way most people, from a chat interface, like ChatGPT or Claude. It worked but had limits. I wanted something embedded into my IDE.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Embedding into the IDE
&lt;/h3&gt;

&lt;p&gt;Now, I use a plugin called &lt;a href="https://continue.dev/" rel="noopener noreferrer"&gt;Continue&lt;/a&gt;, which works in both IntelliJ and Visual Studio Code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially connected to Ollama (local code models)&lt;/li&gt;
&lt;li&gt;Later I Switched to OpenRouter for bigger cloud models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So now, I can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jump into a chat interface via my IDE&lt;/li&gt;
&lt;li&gt;Still use chatbots like Claude/ChatGPT for generic things&lt;/li&gt;
&lt;li&gt;Never look at Stack Overflow anymore, everything’s in the IDE chat&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Agentic Coding
&lt;/h3&gt;

&lt;p&gt;I started using agentic tools, like OpenCode, on the command line. They can scan my whole codebase, not just what’s open in the IDE.&lt;/p&gt;

&lt;p&gt;I use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a page object model for a URL&lt;/li&gt;
&lt;li&gt;Write a test for that model&lt;/li&gt;
&lt;li&gt;Generate K6 Scripts&lt;/li&gt;
&lt;li&gt;Create swagger files&lt;/li&gt;
&lt;li&gt;Write scripts&lt;/li&gt;
&lt;li&gt;Write API Abstractions&lt;/li&gt;
&lt;li&gt;… so much&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now instead of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing the test&lt;/li&gt;
&lt;li&gt;Building abstractions and models manually&lt;/li&gt;
&lt;li&gt;Iteratively improving&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I let the AI generate code, then I come in and change or adapt what I need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m using it as a tool to help me create things faster. Then I come in and use my knowledge and experience to review the code or expand it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4: OpenSpec for Better Requirements
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Fission-AI/OpenSpec" rel="noopener noreferrer"&gt;OpenSpec&lt;/a&gt; helps generate and maintain evolving and up to date requirements documentation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specs are continuously updated as requirements change&lt;/li&gt;
&lt;li&gt;OpenCode has documentation to work from, in addition to my prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I use OpenSpec, I’m letting the Agentic Coding Assistant write even more code, than when I use it iteratively at the CLI.&lt;/p&gt;

&lt;p&gt;This has helped me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;write a new application faster&lt;/li&gt;
&lt;li&gt;Keep requirements and documentation in sync&lt;/li&gt;
&lt;li&gt;Automate coverage incrementally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not sure how well it would scale to a full team, but it works well for a solo dev.&lt;/p&gt;

&lt;p&gt;But…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI sometimes makes strange design choices&lt;/li&gt;
&lt;li&gt;If you don’t review and refactor, your codebase can fall apart fast&lt;/li&gt;
&lt;li&gt;Human review is still necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI saves time, but still requires fundamental core skills to evaluate their output and fix them when they go wrong.&lt;/p&gt;

&lt;p&gt;I use AI for programming all the time, but not for actual testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agentic AI in Testing
&lt;/h2&gt;

&lt;p&gt;I’m beginning to look into Agentic AI tools specifically designed for testing.&lt;/p&gt;

&lt;p&gt;I’m currently experimenting with AQE Fleet from &lt;a href="https://www.linkedin.com/in/dragan-spiridonov/" rel="noopener noreferrer"&gt;Dragan Spiridonov&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/proffesor-for-testing/agentic-qe" rel="noopener noreferrer"&gt;https://github.com/proffesor-for-testing/agentic-qe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forge-quality.dev/" rel="noopener noreferrer"&gt;https://forge-quality.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pros and Cons
&lt;/h2&gt;

&lt;p&gt;Right now, I am optimistic about AI empowering individual development team members. It makes us faster, and the tools are getting better.&lt;/p&gt;

&lt;p&gt;But I am pessimistic about the way companies choose to adapt to AI. Focus on headcount reduction instead of increased effectiveness and growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Testing?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“I keep seeing posts that testers need to evolve into quality engineers and risk analysts and customer experience advocates because we’ll be reviewing the systems for risk more than we’re and testing them… but I thought we already did those things.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People keep saying testers now need to be risk analysts, customer experience advocates, technical experts, etc. But that’s what good testers have always done. It almost feels like AI is forcing companies to rediscover what software testing really is, and always has been.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>ai</category>
      <category>testautomation</category>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>Free Technical Web Testing Course Released To Youtube</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Thu, 18 Dec 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/free-technical-web-testing-course-released-to-youtube-54p3</link>
      <guid>https://forem.com/eviltester/free-technical-web-testing-course-released-to-youtube-54p3</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; Technical Web Testing course has been released to YouTube as a 6 hour video.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Free Technical Web Testing 101 course
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/jWwfMo5Ziz0"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jWwfMo5Ziz0" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Slides etc. can be found via the &lt;a href="https://www.eviltester.com/page/onlinetraining/techwebtesting101/" rel="noopener noreferrer"&gt;course page&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice Sites Now
&lt;/h2&gt;

&lt;p&gt;The sites I use in the course are a little old.&lt;/p&gt;

&lt;p&gt;If you want to practice with the techniques in the course then I maintain lists of sites to practice with here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/reference/other-sites/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/reference/other-sites/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apichallenges.eviltester.com/practice-sites" rel="noopener noreferrer"&gt;https://apichallenges.eviltester.com/practice-sites&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Course History
&lt;/h2&gt;

&lt;p&gt;The course was created in 2013 or 2014. Originally as a free course, then I added a bunch of content and it turned into 6 hours plus 3 hours of additional webinar content.&lt;/p&gt;

&lt;p&gt;Every course provider I hosted it on has changed terms and conditions multiple times making it painful to maintain and support.&lt;/p&gt;

&lt;p&gt;Since the examples and videos are now showing their age, and one course provider changed their terms and conditions so much that I now no longer have access to their course platform and can’t support it.&lt;/p&gt;

&lt;p&gt;I decided to make the course free.&lt;/p&gt;

&lt;p&gt;The course is too big to make free on Udemy so I’ve combined all the videos into one and made them free on Youtube.&lt;/p&gt;

&lt;p&gt;Thanks to everyone who supported the course over the years.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>An overview of the Basic Shopping Cart Practice Web Page</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Mon, 15 Dec 2025 11:19:00 +0000</pubDate>
      <link>https://forem.com/eviltester/an-overview-of-the-basic-shopping-cart-practice-web-page-i1o</link>
      <guid>https://forem.com/eviltester/an-overview-of-the-basic-shopping-cart-practice-web-page-i1o</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; an overview of the basic shopping cart that you can use to explore, automate through the UI or REST API and perform security testing on.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Shopping Cart Application offers a lot of possibility for testing due to the multi-state and multi-page nature. With the added bonus of a REST API which is documented using OpenAPI spec there are even more ways to interact with it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/apps/basiccart/" rel="noopener noreferrer"&gt;Find the Shopping Cart Application Here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview Video
&lt;/h2&gt;

&lt;p&gt;The video provides an overview of the shopping cart:&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/KrpD5RtmDb0"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=KrpD5RtmDb0" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Shopping Carts for Practicing
&lt;/h2&gt;

&lt;p&gt;This is not the first Shopping Cart practice Application.&lt;/p&gt;

&lt;p&gt;I know of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.saucedemo.com/" rel="noopener noreferrer"&gt;SwagLabs&lt;/a&gt; Saucelabs demo application.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://practicesoftwaretesting.com/" rel="noopener noreferrer"&gt;Toolshop&lt;/a&gt; from this has &lt;a href="https://testsmith.ams3.cdn.digitaloceanspaces.com/artifacts/practicesoftwaretesting-bookmarks.html" rel="noopener noreferrer"&gt;multiple versions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://automationintesting.online/" rel="noopener noreferrer"&gt;Restful Booker&lt;/a&gt; could be classed as a shopping cart&lt;/li&gt;
&lt;li&gt;and my &lt;a href="https://testpages.eviltester.com/apps/basiccart/" rel="noopener noreferrer"&gt;Basic Shopping Cart&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SwagLabs is pure JavaScript so there are no HTTP calls, but you can explore and test the interaction with local browser storage, and the various users that you can login with change the display so you can use it for visual testing and admin access.&lt;/p&gt;

&lt;p&gt;Toolshop, Restful Booker and my Shopping Cart all have APIs and the data is cleared regularly. I think Restful Booker clears data every 15 minutes. Shopping Cart clears data on a rolling basis by limiting the amount stored, so if there are a lot of users at any one time (about 200+), you might notice your old orders clearing from the backend.&lt;/p&gt;

&lt;p&gt;When I was designing the Basic Shopping Cart I very deliberately chose to make sure that there was no possible way of having any PI data in the system. This meant that the checkout process does not ask for email addresses, credit card details, or even passwords. The users are ‘canned’ with pre-defined passwords. This means you can perform security testing without any issues.&lt;/p&gt;

&lt;p&gt;Really you shouldn’t add any PI data to any testing practice site, but when applications use forms, the auto-complete might be switched on, and your details might be auto-populated into the form.&lt;/p&gt;

&lt;p&gt;I do like the other Shopping Carts and have used all of them when practicing my testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why A Shopping Cart?
&lt;/h2&gt;

&lt;p&gt;Shopping Cart applications offer a lot of scope.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There tend to be multiple pages offering navigation scope.&lt;/li&gt;
&lt;li&gt;Pagination if there are enough products.&lt;/li&gt;
&lt;li&gt;API and server side interaction.&lt;/li&gt;
&lt;li&gt;Checkout Process has state - tracked locally via cookies or browser storage, and possibly server side as well. Having state in two places offers scope for state moving out of sync and creating mismatch between server and client.&lt;/li&gt;
&lt;li&gt;Usually a registration or login process. Which also lends itself to security testing.&lt;/li&gt;
&lt;li&gt;Tend to be content rich.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Content rich applications are interesting. The first time we automate them we tend to hard code product names and ids. Then we realise that there is usually a CMS (Content Management System), and users can edit content, which then causes our automated execution to fail.&lt;/p&gt;

&lt;p&gt;This might lead us to using the API and UI as a consistency Oracle for content. Does the API serve data consistently. Is the data rendered correctly. So we don’t automate or test exclusively through the UI, we use the UI and API in combination when we want to assert on data conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creation of the Shopping Cart
&lt;/h2&gt;

&lt;p&gt;To build the application I started API first. The API was completely hand coded. This meant that I could test the flows and the functionality before spending any time on the UI. I was able to experiment with various authentication flows and data representations until I had one that I thought was rich enough and removed any PI risks.&lt;/p&gt;

&lt;p&gt;Once I had the backend covered I used &lt;a href="https://opencode.ai/" rel="noopener noreferrer"&gt;OpenCode&lt;/a&gt; to incrementally add basic REST API automated coverage, and then expanded the coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frond End Creation
&lt;/h2&gt;

&lt;p&gt;I wanted the front-end to be simple JavaScript, HTMl and CSS, and avoid the use of frameworks.&lt;/p&gt;

&lt;p&gt;My Test Applications are designed to be entry points. They will be challenging enough naturally, so I didn’t want to clutter the learning effort for people practicing by using React.&lt;/p&gt;

&lt;p&gt;The Front End was creating by prompting through OpenCode and then I would amend and refactor where necessary. This allowed me to create the front-end quickly. But because I prompt in very small increments the code is more closely aligned with the style of coding I use, and makes it easier for me to amend in the future.&lt;/p&gt;

&lt;p&gt;The models used were spread across free models from &lt;a href="https://opencode.ai/zen" rel="noopener noreferrer"&gt;OpenCode Zen&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grok Code Fast 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or I used &lt;a href="https://openrouter.ai/kwaipilot/kat-coder-pro:free" rel="noopener noreferrer"&gt;Kat Coder Pro (free)&lt;/a&gt; on OpenRouter.&lt;/p&gt;

&lt;p&gt;I try to use a mix of models in the CLI, and then a different set of models in the IDE. In the IDE I have &lt;a href="https://continue.dev/" rel="noopener noreferrer"&gt;Continue&lt;/a&gt; configured to use OpenRouter models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Content
&lt;/h2&gt;

&lt;p&gt;Al the content was generated via AI tooling.&lt;/p&gt;

&lt;p&gt;I prompted GTP-OSS-20B via OpenRouter to create 100 ’thing’ name variations. I fed it the sample ’thingy’ words and adjectives. I could have varied this more, and I could easily have used a normal combinatorial algorithm to do this but the AI interface was fast enough.&lt;/p&gt;

&lt;p&gt;With a set of 100 names, I then asked for one line descriptions, using the same process. The are all output as JSON to make it easy for me to amend in the code.&lt;/p&gt;

&lt;p&gt;Since this data is ‘content’ I can vary it over time. For the first release I just need 100 different products to add to the product list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Product Images
&lt;/h2&gt;

&lt;p&gt;Generating the images was a little more interesting.&lt;/p&gt;

&lt;p&gt;I am deliberately trying to keep my AI cost as low as possible to see how far I can push my use of AI with minimal cost.&lt;/p&gt;

&lt;p&gt;My biggest cost on OpenRouter was using Nano Banana to create 2 experimental images when it was first released. The Nano Banana images cost 50c each and they didn’t end up the way I wanted. This was not an experiment I wanted to repeat with the product images. I’d need at least 100 and I might want to regenerate them if they didn’t work out.&lt;/p&gt;

&lt;p&gt;First I tried image generation models through the local install of &lt;a href="//httpsL//localai.io"&gt;localai.io&lt;/a&gt; but I don’t think my machine is powerful enough. The process was slow and the output was basically a random png and completely unsuitable.&lt;/p&gt;

&lt;p&gt;Rather than spend another couple of hours experimenting to improve this, I decided to try one of the image models on OpenRouter. These are easy to automate but past experience made me hesitant. However, as I was looking at the costs I noticed that the image pricing was quite cheap for one of the models, but this was only shown in the comparison page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openrouter.ai/compare/openai/gpt-5-image-mini/google/gemini-3-pro-image-preview" rel="noopener noreferrer"&gt;https://openrouter.ai/compare/openai/gpt-5-image-mini/google/gemini-3-pro-image-preview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GPT 5 Image Mini was estimated at $0.002 per K generated.&lt;/p&gt;

&lt;p&gt;I didn’t expect to have good results with this but I tried it through a simple prompt and was surprised at the image quality.&lt;/p&gt;

&lt;p&gt;It took me about 20 minutes to write code to call the API and experiment with prompts. This led to some good random product images and they were about $0.007 per image, so I could generate 100 images for about $0.70.&lt;/p&gt;

&lt;p&gt;I used the product descriptions generated earlier and fed them through into OpenRouter with my script to generate the images you can see in the product pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Image Descriptions
&lt;/h2&gt;

&lt;p&gt;Rather than use Lorem Ipsum I wanted to generate fanciful and long descriptions for each of the products.&lt;/p&gt;

&lt;p&gt;I wanted to use AI to generate a fuller paragraph style description of each product.&lt;/p&gt;

&lt;p&gt;I found that the lava:7b model will run nicely on Ollama locally and it is very small. It has vision capabilities, so it can read images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ollama.com/library/llava:7b" rel="noopener noreferrer"&gt;https://ollama.com/library/llava:7b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It only consumes about 5gb when running so it fits comfortably in my GPU memory.&lt;/p&gt;

&lt;p&gt;I used this via api calls to describe each of the images in turn. I was very surprised at the quality of the descriptions when running locally.&lt;/p&gt;

&lt;p&gt;This worked out well enough for my experiment and in total cost around $0.70 to generate and describe 100 images.&lt;/p&gt;

&lt;p&gt;I thought that 100 was enough to allow pagination experiments and build on over time.&lt;/p&gt;

&lt;p&gt;In total to do all this programmatically took about an hour to write code and 4 hours to run.&lt;/p&gt;

&lt;p&gt;I think it would probably have taken longer for me to search the web, find a tool to do all this, if a single tool even existed at all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tool Vendors Take Note: it is becoming easier and easier for people to create their own tooling, cheaply and with the exact functionality they need.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Automating the Web UI
&lt;/h2&gt;

&lt;p&gt;I used OpenCode to generate the Page Object Models and an initial set of coverage, I then amended and refactored to expand the coverage as I required.&lt;/p&gt;

&lt;p&gt;This has become my normal approach to generating automated execution code now. This is also different from the way I code manually.&lt;/p&gt;

&lt;p&gt;When coding manually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I write the test first,&lt;/li&gt;
&lt;li&gt;and grow the Page Object Model organically through refactoring,&lt;/li&gt;
&lt;li&gt;this way I only create the abstraction code that I need in the test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When coding with AI, I reverse this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I generate the Page Object

&lt;ul&gt;
&lt;li&gt;I give OpenCode access to the Chrome Dev Tools MCP so that it can read the DOM and it generates accurate locators. Sometimes I refine them, but they are usually good enough.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;During the Page Object creation, in the same prompt I ask for

&lt;ul&gt;
&lt;li&gt;“A set of basic tests which use the Page Object Model methods to cover the basic functionality. Do not test the Page Object, use the Page Object to avoid putting any locators for ‘driver.’ methods in the test code.”.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;I then review and refactor.&lt;/li&gt;

&lt;li&gt;Then I iteratively expand with small prompts, targeting specific coverage with each prompt.&lt;/li&gt;

&lt;li&gt;I’ve found this works well, avoids rework and is fast.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automating the REST API
&lt;/h2&gt;

&lt;p&gt;I prompted OpenCode to read the routing code that I had written in Java for the API and create basic coverage for the each of the API end points in turn. This led to the creation of the payload objects and incrementally build up an API abstraction.&lt;/p&gt;

&lt;p&gt;By targeting each endpoint individually I could gradually grow the code, keep control of it, make sure it was using my style of coding and automating and didn’t need a lot of refactoring later.&lt;/p&gt;

&lt;p&gt;I then prompted to recreate the UI automated execution flows using only the API abstractions that I had just built up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;The general rule we are told is that you test first, then automate. You can see from the above description that I do not abide by this rule.&lt;/p&gt;

&lt;p&gt;I used the automated coverage to handle the basic flows and flush out any simple errors. This creates an automated safety net that can help me when I’m fixing any issues that I find from testing. Without the basic automated coverage I might introduce more errors when fixing bugs than I remove.&lt;/p&gt;

&lt;p&gt;Testing was performed via exploration using Chrome, heavily reliant on the dev tools and viewing requests in BurpSuite.&lt;/p&gt;

&lt;p&gt;I then moved on to testing the REST API directly.&lt;/p&gt;

&lt;p&gt;This helps me build up a list of issues, some of which I fix, but since it is a testing app, some of them I don’t.&lt;/p&gt;

&lt;p&gt;The automated coverage tells me that it can work. My testing convinces me where it fails to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Testing
&lt;/h2&gt;

&lt;p&gt;I coded in some security issues, so I made sure to test these.&lt;/p&gt;

&lt;p&gt;I used Bruno as my API client to explore all these issues.&lt;/p&gt;

&lt;p&gt;Some of them I removed because they would be annoying to the user if exploited when they were trying to test the application, so they are primarily information leakage rather than amendment. But… it might be possible if you test deep enough.&lt;/p&gt;

&lt;p&gt;The only tool used during this process was Bruno to issue requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Testing
&lt;/h2&gt;

&lt;p&gt;I didn’t want to go live with the cart unless I could convince myself that it could handle multiple users.&lt;/p&gt;

&lt;p&gt;I used OpenCode to convert my API automated execution scenarios into &lt;a href="https://k6.io/" rel="noopener noreferrer"&gt;K6&lt;/a&gt; scripted scenarios such that I could scale Virtual Users and hit the application functionality.&lt;/p&gt;

&lt;p&gt;I do not recommend the Shopping Cart as a target for performance testing, that isn’t what it is designed for.&lt;/p&gt;

&lt;p&gt;Butch Mayhew maintains a list of sites designed for practicing Performance testing against in his &lt;a href="https://github.com/BMayhew/awesome-sites-to-test-on?tab=readme-ov-file#performance-testing" rel="noopener noreferrer"&gt;Awesome Sites To Test On&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two from Blazemeter and one from OctoPerf:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.demoblaze.com/" rel="noopener noreferrer"&gt;BlazeMeter Demo Store&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blazedemo.com/index.php" rel="noopener noreferrer"&gt;BlazeMeter Simple Travel Agency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://petstore.octoperf.com/actions/Catalog.action" rel="noopener noreferrer"&gt;Octoperf Pet Store Web&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This took me about an hour in total, because I had to fix a couple of errors in the generated k6 script, but I think using OpenCode saved me a couple of hours since I’m not a K6 expert and have to re-learn it every time I use it.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>Software Testing Podcast - BrowserStack Community QnA - The Evil Tester Show Episode 028</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Fri, 12 Dec 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/software-testing-podcast-browserstack-community-qna-the-evil-tester-show-episode-028-1i65</link>
      <guid>https://forem.com/eviltester/software-testing-podcast-browserstack-community-qna-the-evil-tester-show-episode-028-1i65</guid>
      <description>&lt;p&gt;The answers given during an AMA session held on Discord on the 11th of December 2025, following a live LinkedIn video stream. The session focused on “Mastering Automatability for Test Automation”. The main theme is the concept of Automatability, which I view as &lt;strong&gt;the ability to automate&lt;/strong&gt; , this personal skill is more critical than reliance on specific tools. The discussion covers various topics, including how to separate automation problems from application design issues, dealing with slow UIs and non-automation friendly third-party widgets, evaluating automation readiness, and addressing common architectural failings related to large-scale UI automation.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/OmYp1YCPZSU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eviltester.com/show/028-browserstack-qna/" rel="noopener noreferrer"&gt;Links to audio version of the podcast here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Discord And LinkedIn
&lt;/h2&gt;

&lt;p&gt;This was a Browserstack hosted event. The initial Q&amp;amp;A session started on Linkedin with a conversation between Alan Richardson and David Burns.&lt;/p&gt;

&lt;p&gt;Recording can be found here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/events/7404135559247343616/" rel="noopener noreferrer"&gt;LinkedIn Event&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The session then moved to Discord. The Browserstack discord has many AMA and interviews so is worth signing up to have a look at.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.com/channels/1290239387031961602/1389791860116951100/threads/1447958914791637012" rel="noopener noreferrer"&gt;the Browserstack Knowledge-hub forum on Discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/channels/1290239387031961602/1447958914791637012" rel="noopener noreferrer"&gt;Alan Richardson AMA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other AMA sessions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://discord.com/channels/1290239387031961602/1431252937102987274" rel="noopener noreferrer"&gt;Jason Huggins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/channels/1290239387031961602/1426181624038690857" rel="noopener noreferrer"&gt;Gil Zilberfeld&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.com/channels/1290239387031961602/1415293533090222163" rel="noopener noreferrer"&gt;Testers’s Day Panel with Vikas Mittal, Jenna Charlton and Manish Saini&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join the BrowserStack Community on Discord and discover many more sessions, videos and conversations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.browserstack.com/community" rel="noopener noreferrer"&gt;https://www.browserstack.com/community&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Q&amp;amp;A Session Questions and Summaries
&lt;/h2&gt;

&lt;p&gt;I’ve listed the questions and summary answers. Full answers can be found in the podcast, audio or video, or on the &lt;a href="https://discord.com/channels/1290239387031961602/1447958914791637012" rel="noopener noreferrer"&gt;Discord AMA chat&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 1: Understanding Automatability for a First Automation Framework
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; If I’m building my first test automation framework, what’s the one thing about automatability I should understand?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most important thing to understand is that automatability refers to &lt;strong&gt;your ability to automate&lt;/strong&gt;. By having a strong ability to automate, you become less dependent on specific tools, making it easier to create workarounds and choose from multiple tools. Developing experience in how to automate allows you to succeed more often, and means you are not reliant on a tool interacting with your system, which makes workarounds harder. Automating is fundamentally about your understanding of &lt;em&gt;what&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; to automate, and practicing the application of that ability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 2: Separating Automation Problems from Application Design Problems
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How do you separate automation problems from application design problems?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an issue causes problems when you are automating, I would call it an &lt;strong&gt;automation problem&lt;/strong&gt;. While this problem might be &lt;em&gt;triggered&lt;/em&gt; by an application design problem (such as a state-based system that is hard to track, or features that are harder to automate), the issue itself remains distinct. If the team cannot change the application design, they must figure out how to automate the application as it is. This might involve absorbing the issue, figuring out how to automate it at a different level (not end-to-end), or handling it through testing processes using observability tools like DataDog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 3: Slow UIs and Testability/Automatability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; When dealing with slow UIs is the slowness a testability issue an automatability issue or both?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Slowness is likely &lt;strong&gt;both, and more&lt;/strong&gt; , because it is also a usability/user experience issue. If the slow UI impacts the user experience, it is more likely to be addressed than if it only impacts testing or automation. In cybernetics terms, testers or automators must possess the “requisite variety” to handle the variety (slowness) in the system being tested, which means knowing how to synchronize or potentially cleaning the environment to improve speed. The focus would be on the &lt;em&gt;impact&lt;/em&gt; of the slowness, rather than the slowness itself, and whether the team or its tools can absorb the variation in response times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 4: Handling Non-Automation Friendly Third-Party Widgets
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How do you handle third party widgets like payment gateways that are inherently not automation friendly?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a third-party widget is “not automation friendly” for one tactic (e.g., UI automation), it might become easier to automate by adopting different tactics, such as issuing HTTP requests using cookies collected from the UI. Teams may not need to automate the full flow of the widget, but instead focus on ensuring the widget is &lt;strong&gt;wired up correctly&lt;/strong&gt; within their own application. This can involve only testing partway through the flow, or using a mock or stub in the environment so that the full widget flow doesn’t need to be tested constantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 5: Evaluating Automation Readiness and Consultancy Frameworks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How do you evaluate an application’s automation readiness during consulting? Do you follow a framework?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I do &lt;strong&gt;not&lt;/strong&gt; use a formal consulting frameworks. The closest methodology used is the meta model from Neuro-Linguistic Programming, which involves asking questions to build a model of the client’s environment and processes, comparing it to the reality they face.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.eviltester.com/nlp-for-testers/" rel="noopener noreferrer"&gt;learn more about NLP and Testing&lt;/a&gt; in this paper I wrote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regarding automation readiness, an application is considered ready to automate “as soon as someone wants to automate it”. Readiness is judged by whether the client is prepared to &lt;strong&gt;commit to whatever it takes&lt;/strong&gt; to automate the application at that specific point in time to achieve their desired outcomes, regardless of the application’s current state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 6: Architectural Patterns Failing in Large-Scale UI Automation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; What architectural patterns do you see repeatedly failing when it comes to large scale UI automation?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recurring issues often stem from the team lacking the &lt;em&gt;ability to automate&lt;/em&gt; and consequently blaming the tool for problems, rather than creating necessary workarounds. Common process anti-patterns, not strictly architectural patterns, include deploying differently into test and production environments (not using the same install process).&lt;/p&gt;

&lt;p&gt;A major failure point is &lt;strong&gt;test data maintenance&lt;/strong&gt; , especially trying to use production data or any data that the team does not control. Automating against specific data conditions without control over that data causes random test failures. This can be worked around by hardcoding tests against data &lt;em&gt;conditions&lt;/em&gt; instead of specific data, and dynamically selecting the required data during execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 7: Prioritizing Testability and Automation in Sprint Planning
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; If testability improves debugging and automation improves scale, how do we prioritize them during sprint planning?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prioritization can be based on &lt;strong&gt;what the team wants to achieve&lt;/strong&gt; (the outcomes) by the end of the sprint, specifically focusing on the expected coverage from testing and automation. It is beneficial to plan for features that need extensive testing to be delivered early in the sprint. Ideally, testing and automating occur in parallel, and teams automate at lower levels (like unit level) to reduce the necessary coverage at the higher UI level. Issues often arise when teams are divided into isolated roles, creating process problems that hinder effective interaction and prioritization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 8: Playwright and the Illusion of Reduced Automatability Design Needs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; Do modern frameworks like Playwright reduce the need for high automatability design or is that an illusion?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is an &lt;strong&gt;illusion&lt;/strong&gt;. Frameworks like Playwright are designed to absorb application variability through features like retry mechanisms (for synchronization) and locator strategies (like visible text), which reduces the need for constant notification when minor changes occur. This absorption capability makes Playwright effective for agent-based automation where the goal is checking an end-to-end path and the final result.&lt;/p&gt;

&lt;p&gt;However, this absorption can hide issues that a team might want exposed. Even when using Playwright, developers must still understand how to automate and structure their code using abstraction layers (like page objects, domain objects) to ensure long-term maintainability and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 9: Explaining Automatability as an Investment to Leadership
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How do I explain to leadership that improving automatability is an investment not a delay?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The explanation depends on what is being improved. If improving automatability means increasing the team’s ability to automate, it can be presented as an &lt;strong&gt;investment in staff training&lt;/strong&gt;. If it involves adding technical aids (like IDs in the UI), leadership might perceive it as a delay because they may not value UI execution coverage or may already be confident in unit-level automation. To convince leadership, the team could demonstrate the return on investment by &lt;strong&gt;showing the alternative world&lt;/strong&gt;. This involves comparing the current reality to a scenario where improved automatability allows the team to do beneficial things they otherwise couldn’t, thereby highlighting the value gained.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 10: AI Agents Dealing with Dynamic Elements
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; We are exploring AI agents for our teams and I want to know how does the AI agent deal with dynamic elements like rotating banner banners, third party widgets or AB tests?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How the agent deals with dynamic elements depends on how it works (e.g., building high-level BDD scripts or generating code). Agents often operate on &lt;strong&gt;first principles&lt;/strong&gt;. If an agent uses a BDD approach, it works from a runtime specification and handles dynamic elements because it works from scratch for each execution, constantly aiming to fulfill the objective. For example, if an unexpected pop-up appears, the agent clears it and continues.&lt;/p&gt;

&lt;p&gt;If the agent writes code, it uses what is often called “autohealing”. This process automatically amends the script based on the current application state, prioritizing the achievement of the objective regardless of whether the change is “right”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 11: Early Signals of Flaky Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; What early signals tell you that a feature will become flaky once automated?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Early signals involve understanding the &lt;strong&gt;synchronization points&lt;/strong&gt; of the page. A feature is likely to be flaky if the application is populated or amended over time by JavaScript and the automation tool is not synchronizing properly on the DOM buildup. If a page is being constantly updated in the background without clear visual indicators (like spinners, which are easy to synchronize on), flakiness is more likely.&lt;/p&gt;

&lt;p&gt;The signal is the update process itself, particularly when it is non-deterministic (e.g., how totals are updated in a shopping cart). The core question is whether synchronization is required to prevent flakiness, and if it is difficult to synchronize, that is a strong signal. If necessary, automatability might be enhanced by adding an extra flag to the DOM to signal when the update is complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 12: Layers to Focus on in Microservices for Automatability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; In microservices setups which layers should teams focus on first to increase overall automatability?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The foundational layer to focus on is the &lt;strong&gt;human understanding&lt;/strong&gt; of the architecture and the requirements for automation. In microservices specifically, teams would typically focus on the &lt;strong&gt;interface layer&lt;/strong&gt; and their ability to automate it while keeping the interface standard.&lt;/p&gt;

&lt;p&gt;If microservices are communicating via HTTP messages compliant with a version standard, automation can be relatively easy. If interfaces are internal and change randomly, issues may arise, requiring attention to managing event-based queues if applicable. Strategies include using versioned interfaces or having a process to update automated coverage and abstraction layers when microservice interfaces change. It is crucial to avoid replicating interface objects (like payload objects) directly into test code, as this can prevent tests from spotting issues when new or removed fields occur in the application interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 13: Budget-Limited Automatability Fixes for Fastest ROI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; For a team with limited budget which problems around automatability should we fix first to get the fastest return on investment?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The fastest return on investment comes from enhancing the team’s &lt;strong&gt;ability to automate&lt;/strong&gt;. This improvement allows teams to develop workarounds, find alternative solutions, and identify when to use different techniques. It is not about purchasing multiple or expensive tools. Instead, investment could be placed in training, practicing, exploring the capabilities of existing tools, and eliminating fundamental issues like test flakiness by fixing the root causes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 14: Collaborating Earlier to Avoid Automatability Rework
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How can developers and testers collaborate earlier to avoid expensive rework on automatability issues?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Collaboration is achieved by &lt;strong&gt;removing the barriers&lt;/strong&gt; that cause people to be isolated into silos, such as separate programming, testing, or test automation teams. The core issue is often that a “development team” is defined only as a programming team, instead of encompassing responsibility for design, programming, product suitability, testing, and production.&lt;/p&gt;

&lt;p&gt;Practical steps include involving the programming team in the automated execution maintenance. When programmers contribute, they often ensure data IDs are present, which removes many hard-to-automate issues typically found during end-to-end testing. Sharing the responsibility for maintenance ensures people understand and resolve related issues earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q&amp;amp;A 15: Automatability in Continuous Delivery and Trunk-Based Development
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; How should teams think about automatability when shifting towards continuous delivery and trunk-based development?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of Answer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This environment requires high automated execution coverage that runs quickly, often with features being merged multiple times a day. Automatability is achieved by ensuring the person or pair responsible for creating a feature is &lt;strong&gt;also responsible for adding automated execution coverage&lt;/strong&gt; (unit tests). These tests demonstrate that the feature has been tested and provide future checks against accidental changes impacting the functionality.&lt;/p&gt;

&lt;p&gt;Teams could focus on structuring unit tests at the &lt;strong&gt;domain level&lt;/strong&gt; (e.g., focusing on users or orders) rather than strictly class level. This approach results in a degree of internal end-to-end flow tests without needing extensive external system testing. Furthermore, application architecture can be designed so that interfaces (like HTTP interfaces) can be tested primarily at the domain level, reducing the need for numerous actual HTTP calls.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>testing</category>
      <category>learning</category>
      <category>automation</category>
      <category>community</category>
    </item>
    <item>
      <title>Convert Chrome Dev Tools Recording to WebDriver Java Code Using Free OpenCode AI Agent</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Mon, 24 Nov 2025 10:19:00 +0000</pubDate>
      <link>https://forem.com/eviltester/convert-chrome-dev-tools-recording-to-webdriver-java-code-using-free-opencode-ai-agent-1cjm</link>
      <guid>https://forem.com/eviltester/convert-chrome-dev-tools-recording-to-webdriver-java-code-using-free-opencode-ai-agent-1cjm</guid>
      <description>&lt;p&gt;&lt;em&gt;TLDR; Record and Playback is a notoriously bad way to automate. But what if we record, then have AI write code from the recording? Answer: it is a little better.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I performed an experiment to try tand demonstrate how to replicate the AI-powered test automation features commonly found in commercial SaaS testing tools using open source solutions. The process involved recording user interactions in an application with Chrome DevTools Recorder, exporting the recording as JSON, and then using an AI tool to convert the JSON into JUnit tests with WebDriver and page objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview Video
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/9P_-9AvucwE"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=9P_-9AvucwE" rel="noopener noreferrer"&gt;Watch on YouTube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this video I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;record some web actions using Chrome Dev Tools recorder&lt;/li&gt;
&lt;li&gt;fail to play them back because record and playback is notoriously bad&lt;/li&gt;
&lt;li&gt;feed the recorded JSON file into OpenCode with a prompt&lt;/li&gt;
&lt;li&gt;check the results of the AI process writing Automated Execution using WebDriver and Java&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We do get working automated coverage out the back. I would need to edit it a little, and if I wanted to do this longer term I would need to amend the prompt to meet my coding preferences.&lt;/p&gt;

&lt;h2&gt;
  
  
  process
&lt;/h2&gt;

&lt;p&gt;I used the triangle application on Test Pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/apps/triangle/" rel="noopener noreferrer"&gt;https://testpages.eviltester.com/apps/triangle/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test Pages has a deliberately hard to automate side bar. The easy automation is through the top level menu.&lt;/p&gt;

&lt;p&gt;But I recorded the Triangle application by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clicking on the side menu bar to open the Triangle application&lt;/li&gt;
&lt;li&gt;and the instructions&lt;/li&gt;
&lt;li&gt;reading the instructions&lt;/li&gt;
&lt;li&gt;clicking back on the triangle application&lt;/li&gt;
&lt;li&gt;interacting with the app to generate invalid and valid triangles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I tried to playback the recording in the Chrome Dev Tools, it failed.&lt;/p&gt;

&lt;p&gt;Most of us experience failure with record and playback tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI tooling
&lt;/h2&gt;

&lt;p&gt;I have OpenCode, configured to use Chrome Dev Tools MCP, and working with Kat Code Pro Free in OpenRouter, but could just as easily have used any of the free coding LLMS on Open Code Zen or with Ollama locally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opencode.ai/" rel="noopener noreferrer"&gt;https://opencode.ai/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ChromeDevTools/chrome-devtools-mcp/" rel="noopener noreferrer"&gt;https://github.com/ChromeDevTools/chrome-devtools-mcp/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openrouter.ai/" rel="noopener noreferrer"&gt;https://openrouter.ai/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openrouter.ai/kwaipilot/kat-coder-pro:free" rel="noopener noreferrer"&gt;https://openrouter.ai/kwaipilot/kat-coder-pro:free&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used a basic prompt&lt;/p&gt;

&lt;p&gt;“given the json attached, convert the json into a set of junit tests using webdriver and page objects to recreate the flows recorded by the user. The json file is a recording made in Chrome Dev Tools recorder”.&lt;/p&gt;

&lt;p&gt;The process took about 5 minutes to run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It opened the web page a few times,&lt;/li&gt;
&lt;li&gt;created some Page Objects.&lt;/li&gt;
&lt;li&gt;Found that the menu interaction was hard.&lt;/li&gt;
&lt;li&gt;Decided to jump straight to the triangle page and automate that way&lt;/li&gt;
&lt;li&gt;It did replicate the functional interaction included in the recording&lt;/li&gt;
&lt;li&gt;it did generate assertions for the results&lt;/li&gt;
&lt;li&gt;I could have used the test code generate with some small amendments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;SAAS tools which take this approach will use Agents, which are essentially longer prompts. I should have added into the prompt more conditions:&lt;/p&gt;

&lt;p&gt;“given the json attached, convert the json into a set of junit tests using webdriver and page objects to recreate the flows recorded by the user. The json file is a recording made in Chrome Dev Tools recorder. In the test code, do not write any findElement code, always abstract the location and interaction into a page object. Use existing page objects where possible and try to re-use existing methods. Make sure that any page object methods you use are used in a test so we have coverage of the interactions.”&lt;/p&gt;

&lt;p&gt;Over time, if I wanted to continue to automate using this process, I would refine the prompt further until I got the results I wanted, and possibly encode this prompt as an agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would I do this?
&lt;/h2&gt;

&lt;p&gt;Unlikely that I would do this in the real world.&lt;/p&gt;

&lt;p&gt;This seems like the replication of a record and playback approach.&lt;/p&gt;

&lt;p&gt;I do create Page Objects and have created initial execution coverage using AI.&lt;/p&gt;

&lt;p&gt;I have some empathy for AI tooling scanning applications and building flows through the application to automatically interact and generate a wide variety of data, to increase the scope of coverage across a few simple flows. I can see potential in augmenting a team to allow the team to go off and do more detailed stuff. Provided the AI tooling doesn’t get noisy and keep distracting the team.&lt;/p&gt;

&lt;p&gt;For any functionality as simple as I experimented with here, I hope that when people evaluate SAAS tools, that they also compare the paid tools to the capabilities of Open Source tools.&lt;/p&gt;

&lt;p&gt;Nothing wrong with paid tools. They are incredibly valuable when they make hard things simple, and add value when they make hard things easier.&lt;/p&gt;

&lt;p&gt;But, when the activity is simple and the functionality differences between Open Source and paid are small, I hope companies consider “what if we upskilled our staff a little such that we could use the Open Source tools”.&lt;/p&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>testing</category>
      <category>java</category>
      <category>automation</category>
      <category>ai</category>
    </item>
    <item>
      <title>What tool to choose for Web UI Test Automation?</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Thu, 25 Sep 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/what-tool-to-choose-for-web-ui-test-automation-5gl1</link>
      <guid>https://forem.com/eviltester/what-tool-to-choose-for-web-ui-test-automation-5gl1</guid>
      <description>&lt;p&gt;TLDR; I tried to objectively assess the web automation tool market. And as a new development team I’d probably choose Playwright, but as someone experienced in automating the web I’d still choose WebDriver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reviewing Automation Tools
&lt;/h2&gt;

&lt;p&gt;I reviewed the market for Open Source and free Web Automation Tools so that I could more objectively answer questions like “What tool should we use for Web Test Automation”.&lt;/p&gt;

&lt;p&gt;I tried to approach this like any development team would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web searches for tools&lt;/li&gt;
&lt;li&gt;read forums and comments&lt;/li&gt;
&lt;li&gt;read the documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I also tried to project scalability. If the team starts to create a lot of Web UI coverage and wants to have many different versions of browsers available then which tools also let them use cloud providers as the execution agent.&lt;/p&gt;

&lt;p&gt;This was a thought experiment so I didn’t prototype execution with each tool I have used both tools so for the purpose of this write up I skipped this step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Searches
&lt;/h2&gt;

&lt;p&gt;There are a lot of spam articles on “17 Best Web Automation Tools for 2025”. You could create random variations of this title and probably find an article using your generated title on the web.&lt;/p&gt;

&lt;p&gt;What you find are random lists which lump paid no-code tools with unsupported niche code libraries mixed with commercial AI based tools. Also automation tools (Webdriver, Playwright) would be mixed with execution and design frameworks (Robot, Cucumber).&lt;/p&gt;

&lt;p&gt;An impossible combination to search through and most of those pages offered me no value.&lt;/p&gt;

&lt;p&gt;So the first thing a team has to decide are filtering criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;paid or free and open source?&lt;/li&gt;
&lt;li&gt;code based or no-code based?&lt;/li&gt;
&lt;li&gt;AI or non-AI?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will depend on the team. Development teams with coding skills are probably best served by looking for free code based tools. They will have the skill sets to take advantage of the flexibility provided.&lt;/p&gt;

&lt;p&gt;Test teams with no coding skills will have a harder time choosing tools because there is so much competition for paid, no-code, AI tooling.&lt;/p&gt;

&lt;p&gt;I’m focused on the free and code based tooling because I code, and I work with, Development teams with coding skills.&lt;/p&gt;

&lt;p&gt;I also recommend that teams who are automating without these skills, try to develop these skills as it can help avoid tool lock-in and ultimately opens up more approaches for automating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Community Sentiment Analysis
&lt;/h3&gt;

&lt;p&gt;If I didn’t have much experience with the tools I’d check sentiment analysis and see what people were recommending on Community sites like Reddit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/QualityAssurance/comments/1nj99yc/which_automation_tool_should_we_prefer_for_web/" rel="noopener noreferrer"&gt;which_automation_tool_should_we_prefer_for_web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/QualityAssurance/comments/1khg0uv/any_recommendations_for_test_automation_tools/" rel="noopener noreferrer"&gt;any_recommendations_for_test_automation_tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/QualityAssurance/comments/1ijxs47/as_a_newbie_to_automating_web_app_tests_which/" rel="noopener noreferrer"&gt;as_a_newbie_to_automating_web_app_tests_which&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking at the community comments Playwright is promoted more than Selenium WebDriver.&lt;/p&gt;

&lt;p&gt;WebDriver seems to require a PR boost because it is seen as outdated. This is unfortunate because it isn’t.&lt;/p&gt;

&lt;p&gt;At this point I’d have a smaller list of tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selenium WebDriver&lt;/li&gt;
&lt;li&gt;Playwright&lt;/li&gt;
&lt;li&gt;WebdriverIO&lt;/li&gt;
&lt;li&gt;Cypress&lt;/li&gt;
&lt;li&gt;Puppeteer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And as I start looking through them I realise that if I want the option to use multiple languages I really only have two options: Selenium WebDriver and Playwright. All the other tools require automating in TypeScript.&lt;/p&gt;

&lt;p&gt;Multi-language support is only offered by Selenium WebDriver and Playwright, all other tools are aimed at JavaScript/Typescript. This is probably a natural side-effect that ‘web applications’ have a front end that is a mix of HTML, CSS and JavaScript so the obvious choice to automate the front end is using the language space of the web: which is TypeScript and JavaScript. But, many teams are polyglot with a mix of skill sets. The core development skill for a large application is going to center on the main code base, which is likely the back-end, and that might well be written in TypeScript, but could equally be Java or Python.&lt;/p&gt;

&lt;p&gt;A library with support for multiple languages is likely to the be choice for most polyglot environments.&lt;/p&gt;

&lt;p&gt;My two main choices for Web Automated Execution driven by coding would be Selenium WebDriver and Playwright.&lt;/p&gt;

&lt;p&gt;The community comments might lead me to think that WebDriver is flaky and hard to use. But I’ve never found WebDriver hard to use, or to be the the root cause of flakiness in my execution. I’ve never needed self-healing locators or auto-waits for stability.&lt;/p&gt;

&lt;p&gt;Some comments against WebDriver: “you need to have the right driver installed for the browser” were removed a long time ago, first by the Selenium Manager library and now this is built in to WebDriver so it is very easy to get started with WebDriver since it downloads drivers and browsers when required. &lt;a href="https://www.selenium.dev/documentation/selenium_manager/" rel="noopener noreferrer"&gt;Selenium Manager&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I read community comments about WebDriver driver and browser management I might be concerned, but I’d then see in the Playwright documentation that I have to manage the browsers for playwright using maven or &lt;code&gt;npm&lt;/code&gt; commands &lt;a href="https://playwright.dev/java/docs/browsers" rel="noopener noreferrer"&gt;see browers docs&lt;/a&gt;. The documentation for Playwright actually makes this seem harder than it needs to be because I’m pretty sure I’ve never done this with Playwright and it downloaded what it needed automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability Support - Online hosts for Web Automation Tools
&lt;/h3&gt;

&lt;p&gt;Reviewing the online Web Automation SAAS tools can give a good indication of which libraries and tools are popular and scalable.&lt;/p&gt;

&lt;p&gt;If you start using a tool heavily then you might want to expand the range of browsers that you automate against, this can be time consuming to setup locally so Online hosts might help by pointing the test code at a cloud instance for a specific browser.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BrowserStack

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.browserstack.com/" rel="noopener noreferrer"&gt;https://www.browserstack.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Selenium, Playwright, Cypress, Puppeteer, WebDriverIO&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;LambdaTest

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.lambdatest.com/" rel="noopener noreferrer"&gt;https://www.lambdatest.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Selenium, Playwright, Cypress, Puppeteer, WebDriverIO&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;SauceLabs

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.lambdatest.com/" rel="noopener noreferrer"&gt;https://www.lambdatest.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Selenium, Playwright, Cypress, WebDriverIO&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;TestingBot

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testingbot.com/" rel="noopener noreferrer"&gt;https://testingbot.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Selenium, Cypress, Puppeteer, Playwright, WebDriverIO&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Reading the documentation for these tools I’d learn of other tools which are mentioned when looking through docs of online hosts e.g. TestCafe, Nightwatch. But again these are not polyglot so wouldn’t really expand my options.&lt;/p&gt;

&lt;p&gt;At this point I’d also see that with my short-list of tools I have options around scalability which don’t require me setting up my own multi browser environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Playwright vs Selenium WebDriver
&lt;/h3&gt;

&lt;p&gt;I narrowed my choice down to Playwright vs Selenium due to multi-language support.&lt;/p&gt;

&lt;p&gt;So now I have to go through the thought process of comparing the tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Perceived Execution Speed and Coverage
&lt;/h3&gt;

&lt;p&gt;Playwright has the advantage that it is newer and only targets a subset of browsers and browser communication protocols, it has no support for legacy browsers, it has never had to concern itself with backwards compatibility.&lt;/p&gt;

&lt;p&gt;If you need to use legacy browsers then you’ll probably use WebDriver.&lt;/p&gt;

&lt;p&gt;Both WebDriver and Playwright are converging on the &lt;a href="https://www.w3.org/TR/webdriver-bidi/" rel="noopener noreferrer"&gt;WebDriver BiDi W3C standard&lt;/a&gt;, so when this happens a choice between WebDriver and Playwright is likely to come down to the programmer oriented API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;Comparing the Playwright and WebDriver documentation and we can see the advantage that a tool with Big Company support has.&lt;/p&gt;

&lt;p&gt;Playwright is provided by Microsoft and has people paid to work on the documentation and examples. WebDriver is community driven and so naturally the Playwright documentation is currently more attractive than WebDriver.&lt;/p&gt;

&lt;p&gt;For an experienced team this isn’t really an issue because the WebDriver API is very well documented at the code level and both projects have example code on Github.&lt;/p&gt;

&lt;p&gt;For a team just starting out the documentation page and community comments could well swing people over to Playwright immediately but I would hope this wouldn’t be a deciding factor for experienced teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto Waits and Retries
&lt;/h3&gt;

&lt;p&gt;Playwright is probably also viewed as ’easier’ because of the auto-waits. I have some experience with automating so this actually makes me nervous, I’ve seen auto-waiting and auto-synchronisation cover up application bugs.&lt;/p&gt;

&lt;p&gt;The auto-wait conditions are documented on the Playwright site under &lt;a href="https://playwright.dev/docs/actionability" rel="noopener noreferrer"&gt;actionability&lt;/a&gt; Here I can see the automatic synchronisation on &lt;code&gt;check&lt;/code&gt;, &lt;code&gt;click&lt;/code&gt;, etc. I checked the Playwright documentation and see that I can &lt;a href="https://playwright.dev/docs/test-timeouts" rel="noopener noreferrer"&gt;configure the auto-wait action timeouts&lt;/a&gt; so I can take control over that behaviour when necessary.&lt;/p&gt;

&lt;p&gt;Playwright has auto-retrying assertions &lt;code&gt;expect(locator).toBeEditable()&lt;/code&gt; which seem analogous to the &lt;code&gt;WebDriverWait&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  API Coverage
&lt;/h3&gt;

&lt;p&gt;The addition of API coverage from a single tool might push teams towards Playwright.&lt;/p&gt;

&lt;p&gt;I personally prefer tools and libraries to be focused on ‘one thing’ and do it well&lt;/p&gt;

&lt;p&gt;API coverage can easily be achieved on projects using WebDriver by adding specialised libraries for the coverage required e.g. HTTP libraries for API testing and mocking libraries for APIs.&lt;/p&gt;

&lt;p&gt;The dynamic mocking that Playwright supports where network traffic from the current page are mocked is harder to achieve with WebDriver and requires Network access. But also, is that the ‘right’ place to test that functionality? I’d expect to see that covered pre-deployment at the code level rather than running integration level and would expect that to be covered by &lt;a href="https://testing-library.com/" rel="noopener noreferrer"&gt;testing-library.com&lt;/a&gt; level component tests with a mock API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Project Scope
&lt;/h3&gt;

&lt;p&gt;For me, this API Coverage might act as a Risk that the scope of Playwright expands beyond what I would require.&lt;/p&gt;

&lt;p&gt;The scope of Playwright might be trying to evolve to cover deployed application execution and component development testing (like Cypress or &lt;a href="https://testing-library.com" rel="noopener noreferrer"&gt;Testing Library&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I can also see that there are differences in functionality between the language variants with the Node.js version offering a web server for local execution. This also makes me concerned about future viability of some of the languages. Would Java always be a first class citizen in the Playwright world?&lt;/p&gt;

&lt;p&gt;Since the feature set between Playwright and WebDriver isn’t too different, I probably wouldn’t worry too much about this because most of my library usage would be behind a set of abstraction layers and I’d be able to migrate the implementation of those layers to other tools if necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to choose?
&lt;/h2&gt;

&lt;p&gt;If I was new to automating I’d probably choose Playwright.&lt;/p&gt;

&lt;p&gt;I’d be nervous about the differences in language support, but it probably wouldn’t be enough to stop me. If I was automating in TypeScript it probably wouldn’t concern me because I suspect TypeScript is the primary supported language for Playwright. For &lt;code&gt;.Net&lt;/code&gt; I probably wouldn’t be concerned because &lt;code&gt;.Net&lt;/code&gt; is Microsoft and they’ll keep supporting it.&lt;/p&gt;

&lt;p&gt;Both tools are very good, they are maintained, they are both fast, they are both converging on BiDi. Playwright has extra features, many of which can be added to WebDriver projects using other libraries.&lt;/p&gt;

&lt;p&gt;But this is a hard choice. And is probably determined by the feature set that you think you need for automating.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Minority View
&lt;/h2&gt;

&lt;p&gt;I feel that I’m in a Minority at this point. For production web automating I’d still choose Selenium WebDriver with Java or Kotlin.&lt;/p&gt;

&lt;p&gt;I have a strong preference for single-focus libraries that do not try to extend their functional remit too far so that helps sway me towards WebDriver so I personally would still choose WebDriver for production work, but I acknowledge that I am biased based on my previous exposure to WebDriver.&lt;/p&gt;

&lt;p&gt;I’m pretty sure that when the WebDriver BiDi standard is moved out of draft and supported fully by all browsers that the differences between WebDriver and Playwright will be minimal, but WebDriver may have lost a lot of the installed user-base by that point as people have moved towards Playwright.&lt;/p&gt;

&lt;p&gt;The weight of public opinion at the moment is pushing towards Playwright which I think is also a pity because the standards that make Playwright possible were created and pushed by the WebDriver project team.&lt;/p&gt;

&lt;p&gt;There is obviously more money behind Playwright, but it’s free and Big Companies often choose not to support tools for business reasons. This risk feels unlikely to happen but it’s in the back of my mind.&lt;/p&gt;

&lt;p&gt;I think WebDriver remains an essential part of the Web Automation eco-system and it is unfortunate that the Big Browser Companies like Microsoft, Google, Apple are not listed on the &lt;a href="https://www.selenium.dev/sponsors/" rel="noopener noreferrer"&gt;Selenium WebDriver sponsors page&lt;/a&gt;. Despite this the WebDriver team manage to continue to push for open standards that make automating the web easier and better, and maintain tooling across languages and browsers that other tools do not support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple Language Support Tools Summary
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selenium WebDriver
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.selenium.dev/documentation/webdriver/" rel="noopener noreferrer"&gt;https://www.selenium.dev/documentation/webdriver/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Programming languages supported: Java, Python, CSharp (.Net), Ruby, JavaScript, Kotlin(Java)&lt;/li&gt;
&lt;li&gt;Browsers: Chrome, Edge, Firefox, IE, Safari&lt;/li&gt;
&lt;li&gt;Functionality is aimed at Browser Automation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Playwright
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://playwright.dev/java/" rel="noopener noreferrer"&gt;https://playwright.dev/java/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Programming languages supported: Java, Python, JavaScript/Typescript (Node.js), .Net&lt;/li&gt;
&lt;li&gt;Documentation has some odd choices&lt;/li&gt;
&lt;li&gt;Functionality covers Browser, API Automation, API Mocking, Assertions, auto-waits, videos, screenshots, traces&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TypeScript/JavaScript Language Tools Summary
&lt;/h2&gt;

&lt;p&gt;There are a lot of tools in this category which I didn’t really look at e.g. &lt;a href="https://nightwatchjs.org/" rel="noopener noreferrer"&gt;Nightwatch&lt;/a&gt;, &lt;a href="https://testcafe.io/" rel="noopener noreferrer"&gt;TestCafe&lt;/a&gt;, and a host of others. In some ways I made life easy by only considering a polyglot team. If you specialise in Typescript and JavaScript then you have a lot of options to evaluate.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebdriverIO
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webdriver.io/" rel="noopener noreferrer"&gt;https://webdriver.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a JavaScript based abstraction on top of WebDriver protocols and Appium and Puppeteer (&lt;a href="https://pptr.dev/" rel="noopener noreferrer"&gt;https://pptr.dev/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Programming languages supported: Node.js (JavaScript/Typescript)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cypress
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cypress.io/" rel="noopener noreferrer"&gt;https://www.cypress.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chrome, Edge, Firefox, WebKit (experimental)&lt;/li&gt;
&lt;li&gt;Programming languages supported: Node.js (JavaScript/Typescript)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Puppeteer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pptr.dev/" rel="noopener noreferrer"&gt;https://pptr.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chrome Dev Team maintained JavaScript library that is an abstraction on top of the WebDriver Bidi protocol, works with Chrome, Chromium and Firefox&lt;/li&gt;
&lt;li&gt;Not recommended for normal Automated Coverage use cases, but if you want something lightweight that only targets a specific browser set, in JavaScript then have a look.&lt;/li&gt;
&lt;li&gt;Programming languages supported: Node.js (JavaScript/Typescript)
&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testautomation</category>
      <category>softwaretesting</category>
    </item>
    <item>
      <title>Software Testing Podcast - Episode 026 - Portfolio Projects - The Evil Tester Show</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Wed, 17 Sep 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/software-testing-podcast-episode-026-portfolio-projects-the-evil-tester-show-670</link>
      <guid>https://forem.com/eviltester/software-testing-podcast-episode-026-portfolio-projects-the-evil-tester-show-670</guid>
      <description>&lt;p&gt;Should you have an online portfolio showcasing your skills and abilities to help get a job?&lt;/p&gt;

&lt;p&gt;It really depends on the recruitment process. But… if I’m recruiting, and you have a profile then I will have looked at it. So it better be good.&lt;/p&gt;

&lt;p&gt;Welcome to The Evil Tester Show! Covering the common question of “Should we have portfolio projects?” Alan shares his experience as both a creator and reviewer of portfolios, covering everything from the dos and don’ts of GitHub repos, to which skills actually benefit from a showcase, and how a well-crafted readme can make a difference. Whether you’re considering building a portfolio, looking to upgrade your current one, or wondering where to focus your efforts, this episode has practical advice to help you stand out as a top 1% applicants and avoid creating a portfolio that could hurt more than help.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/pqqYTmLFj5Y"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.eviltester.com/show/026-portfolio-projects/" rel="noopener noreferrer"&gt;audio and subscribe links here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Episode Summary
&lt;/h2&gt;

&lt;p&gt;A practical look at online portfolios for developers and testers. Covering both trying to find your next role and also looking to switch careers. Most people don’t have public portfolios so that means you can really stand out if you build a good one.&lt;/p&gt;

&lt;p&gt;We explore what actually matters in a portfolio: the difference between learning repos, personal projects, and true showcase projects designed for job hunting. We break down the content that impresses, and the stuff that doesn’t. We emphasize the need for simplicity and quality. Expect to find tips about managing forks on GitHub, writing an effective README, documenting your learning process, and promoting your work across LinkedIn and blogs to maximize visibility.&lt;/p&gt;

&lt;p&gt;Tailor your projects to communicate exactly what you want and make your portfolio a focused sales tool rather than a catch-all for everything you’ve ever coded. Plus, advice on how to keep your repo clean, how to handle learning projects when switching roles or languages, and why you should never be afraid to show that you’re still learning.&lt;/p&gt;

&lt;p&gt;Most recruiters won’t look at your portfolio, but when they do, you’ll want to be in the top 1%. If you do decide to build a portfolio, make sure it represents your best work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline
&lt;/h2&gt;

&lt;p&gt;00:00 Portfolio Value&lt;/p&gt;

&lt;p&gt;The episode starts by discussing the real-world value of online portfolios. Most recruiters don’t look at them, but if the right person does, yours better be impressive. The host shares personal experiences with portfolios and offers perspective on how useful these tools can really be.&lt;/p&gt;

&lt;p&gt;02:59 Stand Out Skills&lt;/p&gt;

&lt;p&gt;We dig into what actually makes you, and your portfolio, stand out. Typical skills tested during interviews like defect writing, test cases, or strategies do not need to be shown off in a repo. Instead, focus on things that make you unique, such as personal opinions, in-depth case studies, or examples of thought leadership. This is often best done through blogs or articles, linked to your GitHub on your LinkedIn profile.&lt;/p&gt;

&lt;p&gt;09:19 Project Types&lt;/p&gt;

&lt;p&gt;A breakdown of project types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning Projects: Messy, experimental, used to learn new tools, languages, or skills. It’s okay if they’re not polished, but document what you learned.&lt;/li&gt;
&lt;li&gt;Personal Projects: Hobbies or interests that show personality and initiative. These don’t need to be perfect but should reflect genuine enthusiasm and curiosity.&lt;/li&gt;
&lt;li&gt;Portfolio Projects (Showcase Projects): Your best, most complete work. These should be polished, well-documented, and focused on the skills you’re trying to sell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Making these distinctions helps recruiters judge your work appropriately. Always clarify the purpose in your README files.&lt;/p&gt;

&lt;p&gt;12:27 Showcase Projects&lt;/p&gt;

&lt;p&gt;Showcase projects are your sales pitch—they need to be as close to perfect as possible. The host shares advice on what to include in a GitHub repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use your profile README to introduce yourself professionally.&lt;/li&gt;
&lt;li&gt;Only include original repos, not forks, to keep things clean.&lt;/li&gt;
&lt;li&gt;Don’t commit IDE or compiled files; use .gitignore.&lt;/li&gt;
&lt;li&gt;Use static analysis tools and add unit tests to show you care about quality.&lt;/li&gt;
&lt;li&gt;Readme documentation should cover project intent, installation instructions, known limitations, and choices made during development.&lt;/li&gt;
&lt;li&gt;Whenever possible, leverage GitHub Actions to show your code works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recency and maintenance matter when looking for work. Keep your portfolio projects updated and relevant.&lt;/p&gt;

&lt;p&gt;19:39 Promoting Yourself&lt;/p&gt;

&lt;p&gt;Once you’ve created a portfolio project, get the word out. Add it to your LinkedIn profile, feature it as a project, and share articles about your work. Updating and promoting your portfolio regularly keeps it visible and demonstrates your ongoing growth.&lt;/p&gt;

&lt;p&gt;21:44 Final Advice&lt;/p&gt;

&lt;p&gt;Most professionals don’t bother with portfolios, a missed opportunity for many, but if you go the extra mile to create one you can stand out. Make sure it’s good, you don’t want to stand out because it’s bad. Even if recruiters don’t look at it most of the time, the right one will, and that’s when it really helps. Sharing your learning and even your mistakes is crucial for personal development, especially as you gain more experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Most developers and testers don’t have a portfolio, so building one sets you apart when it’s high quality.&lt;/li&gt;
&lt;li&gt;A strong online portfolio acts as a sales tool, focusing on your best, most relevant skills for the job you want.&lt;/li&gt;
&lt;li&gt;Differentiate between learning projects, personal hobby repos, and polished, focused showcase repositories.&lt;/li&gt;
&lt;li&gt;Keeping documentation clear, and up-to-date is just as important as good code in your portfolio.&lt;/li&gt;
&lt;li&gt;Promoting your portfolio on platforms like LinkedIn and your blog can drive the right attention.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quotes
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Should you have an online portfolio showcasing your skills and abilities and will that help you get a job? Well, I got an online portfolio, I’ve had one for years. But I also know that people don’t look at it.”&lt;/p&gt;

&lt;p&gt;“If you’ve got a portfolio and it’s bad, it might put interviewers off. If you’ve got a learning project and you’ve been copying someone on YouTube… When people look at that, they’re gonna go, ‘This person doesn’t know what they’re doing.’”&lt;/p&gt;

&lt;p&gt;“What you want to showcase is something that makes you different, a reason why someone would pick you up as opposed to someone else.”&lt;/p&gt;

&lt;p&gt;“Portfolio project says, ‘I know how to do this, therefore judge me on the work.’ A learning project is, ‘I learned from these other people.’”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join our Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>github</category>
    </item>
    <item>
      <title>Software Testing Podcast - Episode 025 - The Respect Episode - The Evil Tester Show</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Sun, 07 Sep 2025 09:00:00 +0000</pubDate>
      <link>https://forem.com/eviltester/software-testing-podcast-episode-025-the-respect-episode-the-evil-tester-show-4f7f</link>
      <guid>https://forem.com/eviltester/software-testing-podcast-episode-025-the-respect-episode-the-evil-tester-show-4f7f</guid>
      <description>&lt;p&gt;In this episode we discuss respect in the world of software development, with a particular focus on the relationship between testers and programmers. The question isn’t just, “Do testers get enough respect?” but also, “Are you getting the respect you deserve, and do you deserve it?” The episode challenges individuals to evaluate their own skills, contribution, and attitudes.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/TjN2Fw0XITk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Ever feel like you’re not getting the respect that you deserve in your job? This episode dives deep into the Respect in tech, especially focusing on software testing versus programming. We look at why some roles seem to earn more respect, what that means for workplace culture, and how you can change things for yourself and your team. Respect isn’t just about manners or titles - it’s about how the system works and how we show up in our roles.&lt;/p&gt;

&lt;p&gt;If you’ve worked in agile projects, you might have heard, “Everyone is a developer.” But some roles seem to get more recognition than others. Is this because of how we define our jobs, or is it just baked into the way our workplaces run? This episode is a call to action, urging everyone to look at respect both at a personal, process and craft level.&lt;/p&gt;

&lt;p&gt;We’re breaking down the difference between self-respect, respect for others, and respect built into your team’s process. You’ll see why just doing your job isn’t enough. You have to own your craft, communicate what you do, and make your contributions visible to earn genuine respect. By the end of this episode, you’ll have practical steps to make respect part of your daily work, whether you’re writing code, testing, building products, or managing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Episode Summary
&lt;/h2&gt;

&lt;p&gt;We shared insights from working on agile teams, where everyone is supposed to be seen as ‘developers’. But in practice, hierarchies pop up, with programmers often getting more respect than testers or product roles. The host argues that respect is a complex mix: it comes from individual skills, how well you integrate with the process, and how visible and valuable your output is.&lt;/p&gt;

&lt;p&gt;If you don’t see value in your role, improvement is near impossible. Respect starts from within, and only then can you genuinely offer respect to your peers. This isn’t just a feel-good statement, the episode offers actionable advice: make your work visible, advocate for process improvement, pair up on tasks, and always keep learning.&lt;/p&gt;

&lt;p&gt;The podcast also explores respect at multiple levels: the craft itself, the skills you bring, and respect for the person. The episode describes veneration as a kind of misplaced awe for work you don’t understand, and why that’s not real respect.&lt;/p&gt;

&lt;p&gt;With the rise of AI, roles like programming might become less mysterious, changing how people view and respect them.&lt;/p&gt;

&lt;p&gt;Finally, there’s a real-world look at dysfunctional organizations. Respect can be drowned out by fear, power plays, and closed processes. Still, the host insists you can make a difference at your touch-points: knowledge sharing, pairing, and fostering visibility.&lt;/p&gt;

&lt;p&gt;Build self-respect, respect your craft, and model peer-to-peer respect every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline
&lt;/h2&gt;

&lt;p&gt;00:00 – Respect Dilemma&lt;/p&gt;

&lt;p&gt;The episode kicks off questioning whether testers get the respect they’re due, or whether programmers get more because their role is seen as more valuable or mysterious. The host points out that not getting respect might mean you have to level up your skills or make your work clearer to others. It’s not just about demanding respect; it’s about doing work that merits it.&lt;/p&gt;

&lt;p&gt;02:41 – Human Level Respect&lt;/p&gt;

&lt;p&gt;Respect isn’t just about roles, it’s about understanding and appreciating what each person brings to the team. The host shares that, on agile teams, the idea that “everyone is a developer” quickly breaks down when programmers get more recognition than testing or product roles. Respect should happen between people, not only between roles.&lt;/p&gt;

&lt;p&gt;06:31 – Self-Respect First&lt;/p&gt;

&lt;p&gt;If you don’t respect your own work, you can’t expect others to. The episode unpacks the concept of self-respect, challenging listeners to evaluate their skills, growth, and own contributions. There’s advice on how to build true self-respect: keep learning, share your skills, and don’t settle for routines that don’t work and don’t challenge you. Recognizing the value of what you do is the starting point for earning respect.&lt;/p&gt;

&lt;p&gt;10:17 – Respect Cycle&lt;/p&gt;

&lt;p&gt;You respect your craft, your peers respect you, and you respect them back. This creates a healthy team dynamic, with everyone functioning as equals, rather than building hierarchies or silos. The host explains how roles should be seen as complementary, with each one necessary for the team’s success, feeding into improvement and renewal.&lt;/p&gt;

&lt;p&gt;15:37 – Knowledge Sharing&lt;/p&gt;

&lt;p&gt;Knowledge sharing is called out as one of the most powerful drivers of respect in teams. The host stresses that sharing what you know builds trust and exposes the complexity behind roles that might otherwise seem simple. It also invites collaboration, helping people step into each other’s shoes. Escape rooms and team pairings are light-hearted but meaningful ways to see one another’s strengths.&lt;/p&gt;

&lt;p&gt;18:53 – Respectful Organizations&lt;/p&gt;

&lt;p&gt;Not all organizations foster respect. Some rely more on fear and command-and-control than genuine appreciation. The host dives into what a respectful culture looks like: leaders who model right behavior, open processes, and team members who feel safe to raise issues. Even in less ideal places, you can foster respect in your sphere by building solid relationships and pushing for honesty in process issues.&lt;/p&gt;

&lt;p&gt;21:26 – Final Thoughts&lt;/p&gt;

&lt;p&gt;The episode closes with the core advice: build self-respect, model it, and offer respect to others as peers. Respect isn’t about elevating someone else above yourself, it’s about recognizing everyone’s value, including your own. When you do this, you help shape a culture and a process where respect is sticky, even if leadership is lacking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Respect in software teams isn’t automatic. It’s influenced by systems, visibility, and personal ownership.&lt;/li&gt;
&lt;li&gt;Self-respect is the foundation for earning and giving respect to others in the workplace.&lt;/li&gt;
&lt;li&gt;Knowledge sharing and pairing are powerful tools for building respect among team members.&lt;/li&gt;
&lt;li&gt;Hierarchies based on fear and power undermine genuine respect and teamwork.&lt;/li&gt;
&lt;li&gt;AI may change how people view and respect software roles, making process visibility and contribution even more critical.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quotes
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“You might not be getting respect because you don’t deserve it. So we need to look at that. We need to make sure that we are capable of doing the role well and selling it properly so that we get respect.”&lt;/p&gt;

&lt;p&gt;“Respect happens at a human level. When we see the value that each individual brings and we honor and respect that in our environment.”&lt;/p&gt;

&lt;p&gt;“You have to start from a point of ‘I have a craft that is worthy of respect, I have a set of skills that are worthy of respect and I know why they are worthy’.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;strong&gt;&lt;a href="https://www.patreon.com/c/eviltester" rel="noopener noreferrer"&gt;Join The Evil Tester Patreon&lt;/a&gt; from as little as $1 a month for early access to videos, ad-free videos, free e-books and courses, and lots of exclusive content.&lt;/strong&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Chrome Dev Tools AI Assistance to Automate UI from Javascript Console</title>
      <dc:creator>Alan Richardson</dc:creator>
      <pubDate>Tue, 26 Aug 2025 17:01:49 +0000</pubDate>
      <link>https://forem.com/eviltester/using-chrome-dev-tools-ai-assitance-to-automate-ui-from-javascript-console-4gdn</link>
      <guid>https://forem.com/eviltester/using-chrome-dev-tools-ai-assitance-to-automate-ui-from-javascript-console-4gdn</guid>
      <description>&lt;h1&gt;
  
  
  Automating from Console with AI Assistance
&lt;/h1&gt;

&lt;p&gt;TLDR; Can we use the Chrome Dev Tools AI Assistance to generate code that automates an application from the Javascript console? Answer: Yes we can. Prompt to generate code, iterative amendment of prompts required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using AI Assistance to Generate Automated Execution Code
&lt;/h2&gt;

&lt;p&gt;This video shows how I used the Chrome Dev Tools AI Assistance to generate code to automate a simple application from the Javascrip console:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/OeKxq-9WCo4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating From Console
&lt;/h2&gt;

&lt;p&gt;For years, I have written code to automate and amend applications from the Javascript console. This is actually how I learned Javascript.&lt;/p&gt;

&lt;p&gt;I created a free course on Test Automation U that covers the basic Javascript skills around this topic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://testautomationu.applitools.com/automating-in-the-browser-using-javascript/" rel="noopener noreferrer"&gt;testautomationu.applitools.com/automating-in-the-browser-using-javascript/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And a &lt;a href="https://www.eviltester.com/page/onlinetraining/testautomationujs/" rel="noopener noreferrer"&gt;support page with more resources&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And a &lt;a href="https://www.eviltester.com/page/ebook/hacking-javascript-free-ebook/" rel="noopener noreferrer"&gt;free ebook on the topic&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Assistance
&lt;/h2&gt;

&lt;p&gt;Chrome Dev tools now has an AI Assitance tab with a chat interface designed to help you debug CSS and DOM issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.chrome.com/docs/devtools/ai-assistance" rel="noopener noreferrer"&gt;developer.chrome.com/docs/devtools/ai-assistance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many use cases listed on the official site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix styling issues&lt;/li&gt;
&lt;li&gt;Fix layout issues&lt;/li&gt;
&lt;li&gt;Explain and investigate Network calls&lt;/li&gt;
&lt;li&gt;Explain Javascript source files&lt;/li&gt;
&lt;li&gt;Improve page performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if it can do all that, could it augment my ability to automate applications from the console?&lt;/p&gt;

&lt;p&gt;I decided to find out.&lt;/p&gt;

&lt;h2&gt;
  
  
  7CharVal
&lt;/h2&gt;

&lt;p&gt;The 7CharVal application is a simple application I created with a few bugs in it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it takes an input&lt;/li&gt;
&lt;li&gt;you click a button&lt;/li&gt;
&lt;li&gt;the app outputs if the input was a "Valid Value" or "Invalid Value"&lt;/li&gt;
&lt;li&gt;to be valid the input should be 7 chars&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the application here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testpages.eviltester.com/styled/apps/7charval/simple7charvalidation.html" rel="noopener noreferrer"&gt;testpages.eviltester.com/styled/apps/7charval/simple7charvalidation.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application is surprisingly useful for practicing testing. On Patreon I even released a 200+ page ebook of testing exercises and notes, all built around this tiny application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating 7CharVal from console
&lt;/h2&gt;

&lt;p&gt;I can automate the 7CharVal application from the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let validChars = 
    "*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
let errors = [];

// loop over the ascii chars
for(x=0;x&amp;lt;256;x++){

    let aChar=String.fromCharCode(x);
    let expectValid = false;
    let resultExpected = "Invalid Value";

    // decide if the char should be valid or invalid
    if(validChars.includes(aChar)){
        expectValid=true;
        resultExpected = "Valid Value";
    }

    const checkButton = document.querySelector('input[name="validate"]')

    for(position=0;position&amp;lt;7;position++){

        // create the input string
        let seedString = "0000000";
        let positions = seedString.split("");
        positions[position]=aChar;
        let inputString = positions.join("");

        // input the string
        document.querySelector(
                    'input[name="characters"]').value=inputString;

        // trigger the process
        checkButton.click();

        // get the output
        let result=document.querySelector(
                    'input[name="validation_message"]').value;

        // document the result
        let reportLine = 
            `Input: "${inputString}" Dec: ${x} `+
            `Position:${position} Expected: "${resultExpected}" `+
            `Output: "${result}"`;

        // add an alert in the reportif it is not what we expected
        let resultPrefix = "";
        if(result!==resultExpected){
            resultPrefix = "**ERROR** ";
            reportLine = `${resultPrefix} ` + reportLine;
            // separate errors out into their own report
            errors.push(reportLine);
        }
        // document all the results
        console.log(reportLine);
    }
}
// report on the errors
console.table(errors);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iterates over 256 ascii chars&lt;/li&gt;
&lt;li&gt;and adds the char into each of the 7 positions of the input string&lt;/li&gt;
&lt;li&gt;and checks if the generated string is correctly marked as Valid or Invalid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took me about 20 minutes to write by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using AI Assistance to write Code
&lt;/h2&gt;

&lt;p&gt;During the iteration of prompts I decided to take a slightly different approach to automating the application and generated a wider range of inputs rather than picking a single character in a single position. This makes isolating single character issues more difficult but can provide a wide set of data inputs to flush out combination issues. e.g. strings like 'Fe7Nsbb', 'znOzzQg', '7O2i29a', 'wqOdesY', 'ghRGLCO', 'lLrwH*j'&lt;/p&gt;

&lt;p&gt;The full write up of this experiment is on my AI Experiments repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/eviltester/ai-supported-testing-experiments" rel="noopener noreferrer"&gt;github.com/eviltester/ai-supported-testing-experiments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/eviltester/ai-supported-testing-experiments/blob/main/browser-automating/chrome-browser-ai-assistance/automate-7-char-val-console/readme.md" rel="noopener noreferrer"&gt;github.com/eviltester/ai-supported-testing-experiments/blob/main/browser-automating/chrome-browser-ai-assistance/automate-7-char-val-console/readme.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I iterated gradually through a series of prompts. e.g.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create code to run in the Javascript console to enter the string "Aabbccd" into the characters field. Then press the "Check Input" button. Then check that the validation_message field shows the value "Valid Value".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The full set of prompts can be seen in the experiment.&lt;/p&gt;

&lt;p&gt;I tried to avoid relying on the memory context of the AI tooling and kept iterating on the prompt to produce a single output code block.&lt;/p&gt;

&lt;p&gt;And my final prompt ended up as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create code to generate the list of testStrings. The test strings should be 7 characters long. Generate enough test strings such that each of the valid characters should be used at least once in a generated test string. The valid characters are A-Z, a-z, 0-9 and *. Then create code to run in the Javascript console to enter each of the generated test strings into the input field with name "characters". Then press the input element of type button with value "Check Input" button. Then check that the validation_message field shows the value "Valid Value". Add any inputs that pass and generate validation_message "Valid Values" to an array called validInputs. Add any of the input values that fail to generate validation_message "Valid Values" into an array called invalidInputs and throw an exception.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The generated code is below. Copy and paste it into the Javascript console when on the 7charval page and you will automate the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*";
const stringLength = 7;
const requiredCharacters = new Set(characters);
const testStrings = [];
const generatedCharacters = new Set();
let attempts = 0;
const maxAttempts = 10000; // Limit attempts to avoid infinite loops in case coverage is hard

// Generate strings until all characters are covered or max attempts reached
while (generatedCharacters.size &amp;lt; requiredCharacters.size &amp;amp;&amp;amp; attempts &amp;lt; maxAttempts) {
    let randomString = '';
    let stringContainsNewCharacter = false;
    for (let j = 0; j &amp;lt; stringLength; j++) {
        const randomIndex = Math.floor(Math.random() * characters.length);
        const char = characters[randomIndex];
        randomString += char;
        if (!generatedCharacters.has(char)) {
            generatedCharacters.add(char);
            stringContainsNewCharacter = true;
        }
    }
     if (stringContainsNewCharacter || testStrings.length &amp;lt; requiredCharacters.size / stringLength + 5) {
        testStrings.push(randomString);
    }
    attempts++;
}

console.log(`Generated ${testStrings.length} test strings covering all required characters (attempted ${attempts} times).`);

const validInputs = [];
const invalidInputs = [];
const characterInput = document.querySelector('input[name="characters"]');
const checkButton = document.querySelector('input[type="button"][value="Check Input"]');
const validationMessage = document.querySelector('input[name="validation_message"]');

if (!characterInput) {
    console.error("Character input with name 'characters' not found.");
} else if (!checkButton) {
    console.error("Check Input button not found.");
} else if (!validationMessage) {
    console.error("Validation message element not found.");
} else {
    console.log("Starting validation tests...");
    for (const str of testStrings) {
        characterInput.value = str;
        checkButton.click();
        // In some cases, you might need a small delay here for asynchronous updates:
        // await new Promise(resolve =&amp;gt; setTimeout(resolve, 50));
        if (validationMessage.value === "Valid Value") {
            validInputs.push(str);
            console.log(`Input "${str}" passed validation.`);
        } else {
            invalidInputs.push(str);
            console.warn(`Input "${str}" failed validation. Received: "${validationMessage.value}"`);
        }
    }
    console.log('Validation tests complete.');
    console.log("Valid inputs:", validInputs);
    console.log("Invalid inputs:", invalidInputs);


    if (invalidInputs.length &amp;gt; 0) {
        throw new Error("Validation failed for some inputs. See invalidInputs array for details.");
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;The AI tooling was automating the 7charval application during the prompt and summarizing the results of the execution through the LLM.&lt;/p&gt;

&lt;p&gt;I found that the generated code shown to me, was different from the code used by the AI tooling during its execution. The AI tooling liked to put the results in an object but didn't do that in the code provided to me. There is a risk that its code did something different, but that could be solved by code reviews.&lt;/p&gt;

&lt;p&gt;I found the constant reviewing of the code tiresome because each generated block of code was 'new' and I didn't have diffing tools in the chat window to see what was different. I could have pasted it into a diffing tool to aid my review but I gave it a cursory review and became more intersted in the output of the execution.&lt;/p&gt;

&lt;p&gt;The AI Tooling would gradually add extra chars into the final code output making it impossible to copy and paste into the console without first editing the code. It looked like it was trying to add markdown code formatting into the code formatting.&lt;/p&gt;

&lt;p&gt;This was a minor annoyance that I could work around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This feature would have helped me learn Javascript, had it been around when I started automating from the console.&lt;/p&gt;

&lt;p&gt;I will certainly use this in the future to help me generate initial code that I can edit and refine myself.&lt;/p&gt;

&lt;p&gt;I recommend experimenting with the AI Assistance as a code generator for the use case of automating applications from within the browser itself.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaretesting</category>
      <category>testautomation</category>
    </item>
  </channel>
</rss>
