Showing posts with label Playwright. Show all posts
Showing posts with label Playwright. Show all posts

Friday, 17 July 2026

Testing for Coded Apps (automated E2E testing to get high quality)

Overview: Automation testing using AI generally ends with "test rot".  Kaizen Fix gets around test rot by switching the test source from the analysed system requirements to the code source as the logic to test.

Why: Gathering requirements in Agile software is continuously changing, so building tests based on the ask coupled with AI updating code realistically means the behaviour will change, DOM/Shaow DOM updating per build, and the full code base needs to be retested to ensure operational behaviour.

Hypothesis: Break the E2E testing into two distinct parts:
1) Does what the user asked for match what is delivered?  Ask AI to document the requirement from the code and compare it to the requirement the stakeholder signed off on. 
2) When code is updated, does this break any existing logic?  Regression tests to check existing logic work; if not, this requires a man in the loop to validate the change.

Proposed Solution
The four-step loop: 1. Code with AI → 2. Generate the code specification → 3. Tests generated by AI and MCP → 4. Test Baselines (run the dynamic Playwright test suites).  As the release occurs, the developer can automatically run the old tests and identify what is no longer working and why.  This can also be run during development.  I've been working on this different approach: an AI-assisted testing framework that treats the source code as the single source of truth — and turns it into a living, executable specification.

Key Point: reruns against the original/previous baseline catch genuine behaviour changes, not test rot. I deliberately left it unbranded so you can drop in KaizenFix (or keep it vendor-neutral) depending on where you're posting it.

How it works, in four steps:

1. Read the AI-generated code

AI (Claude or GitHub Copilot, working inside the IDE) analyses the application's source — components, routes, validation, business logic — and generates a full behavioural specification: what the system does today, fully documented, straight from the code.

2. Turn behaviour into programmed behaviour requirements

That specification becomes a structured requirements document. Not aspirational requirements — actual behaviour. If the app rounds a value, enforces a limit, or hides a button under a condition, it's captured.

3. Generate the regression suite

From the actual requirements into Playwright tests. AI generates detailed Playwright end-to-end tests — using platform-specific best practices for selectors and patterns, and environment configuration so the same suite runs against dev, UAT, or production. Each web app lives as its own isolated project with its own context and rules.

4. Lock in the baseline

At this point, the tests and the app agree by construction — the suite documents and validates the working behaviour. The tests part of the documentation.

The payoff comes when things change:

When the app or its logic evolves, rerun the original suite. Anything that breaks is a genuine, intentional-or-not change in behaviour — surfaced immediately, with the old expected values as evidence. Regenerate the spec, diff it against the last one, and you can see exactly what changed and whether you meant it. 

Amended +- June 2026 with Picture below: Source unknown


Thursday, 9 July 2026

Azure Container Jobs with Docker containing E2E Playwright testing

Overview: I recently did a great project with Playwright to continuously test Canvas Apps.  This post outlines how I did it.

Reporting: Every test suite run and the tests inside are documented in SharePoint lists. p Below you can see for a project called feedback the tests that verify DTAP Canvas apps (Dev, Test, and Prod).

The Feedback app, in production, is showing the availability tests run recently
 

CI: I decided to use Azure Container Jobs to run the Playwright tests on a Docker image.


Jobs: The Docker image get params and starts the type of tests, the trigger uses cron timing.



Azure Container Job: Each time a job is called, a new instance is created. This means multiple jobs can run simultaneously, and on each job instance I get multiple COUs, so I spawn out 2-4 Playwright processes so the tests run faster.



Friday, 31 October 2025

Playwright Agents in VS Code

I started looking at the latest version of Playwright late last night. The Agents add-in for VS Code is amazing.  I can't stop improving my code, my tests, and my automation.  It is highly addictive.

Playwright 1.56.1 includes the new Playwright CLI, which has the test agents as shown in VS Code above:

Node: v22.21.0
npx: 11.6.2
Playwright test package: ^1.56.1

Sunday, 13 July 2025

E2E Power Platform testing using GitHub and Playwright - advanced

Canvas Apps are particularly challenging for UI and End-to-End (E2E) test automation because Microsoft Power Apps renders much of the application UI within a Shadow DOM. While Shadow DOM provides benefits for Microsoft and app makers, it introduces several obstacles for traditional test automation tools.

Playwright has several key advantages over Selenium and other test tools, mainly around selectors and planning. The selector approach works much better against Canvas Apps that utilise a Shadow DOM.

Selenium tests were flaky as they rely on CSS and XPath to locate elements in the DOM.  Playwright allows users to navigate the DOM within the Page DOM, offering 6-7 ways to find an element, including getByRole().  Selenium often requires many waits/pauses to ensure the DOM is fully loaded, whereas Playwright uses the Page Object Model (POM), and I don't tend to need to use waits on a page.


Define Test Criteria using Gherkin - Go to GitHub Copilot



5    Wh 

*Repeat for multiple features

I believe pairing LLM's to generate context-aware Playwright tests will allow developers and QA engineers to test apps better and faster.

GitHub Spaces  (Not too sure if I like GitHub Spaces)

"Put your code, docs, and notes where they belong: together. With GitHub Copilot Spaces, your AI pair programmer uses that context to deliver better, more tailored answers for you and your team".  Swap between models like Claude 3.7 Sonnet, OpenAI o1, and Google Gemini 2.0 

GitHub Repos, Actions, and Copilot work with VS Code, Visual Studio, and Eclipse.

Monday, 26 May 2025

Playwright Post 6 - Automating Canvas App MFA login for Playwright unattended for Canvas apps

Overview:  Modern security makes automating logins requiring MFA rather difficult.  This post looks at possible approaches to automate the login.

Option 1. Turn off MFA—not really, but you can set a conditional rule in EntraId to not perform MFA. This is not an option in many enterprises.

Option 2. Time-based One-Time Password (TOTP)—Microsoft Authenticator makes this pretty difficult. At least I can't do it, as the APIS are relatively limited. This is kind of expected, as it's a security measure.

Option 3. Programmatically acquire an access token without browser automation, use MSAL with a client secret or certificate (for confidential clients). 

Option 4.  Use Playwright to record the login and intercept the access token once logged in.  Then you can store it and use it.  There are a few easy options to get the session:

4.1. Retrieve the access token from the response once logged in

4.2. Retrieve from your local storage:

  const token = await page.evaluate(() => {
    return window.localStorage.getItem('adal.idtoken') || window.sessionStorage.getItem('adal.idtoken');
  });
4.3. Retrieve the token using Playwright at the command run level

Note: This adds the token to my repository. Don't save the token to your repository if you don't realise that the Access/Bearer token will expire depending on what your EntraId sets. The default is 1 hour.

Option 4.3.1. Like option 4.3, use the refresh token to silently generate a new Access token. You store the refresh token during the recorded login (by default, it lasts for 90 days) to generate a new access token when needed.

Option 4.3.2.  Take it further back to generate the refresh token using the access code you get at the original login, renew the "refresh token", and generate a new access token to run your tests.

If you decide to store your access token, refresh token or code, don't store them in your code repo.  You know why, if you've made it this far.

Thought: as a refresh token works for 90 days on a sliding scale, I've never used the option 4.3.2, as by storing the refresh token, all I need to do is to extend the refresh token by using it to get an access token, and the refresh token has 90 days from that point. 

This is the plan I'm thinking of using:

Monday, 12 May 2025

Playwright Post 5 - Understanding how Playwright Works

Playwright as a tool consists of two main parts.

Part 1: Playwright Library: This is the automation of a browser using the Page Object Model (POM). It provides a uniform API to run against the 3 main browser engines, automating tasks like navigating, clicking, filling in form data, and validating content on a web page. Classes include APIRequest, APIResponse, and BrowserContext. The worker process runs the API calls sequentially. Unified library API calls are sent to the browser context, which runs unaware of the calling context.  

Top link runs in Node.js and makes API library calls, there is no timing between the Node.js (Controller) and the browser instance (running Chromium instance)

Key Terminology:
spec.ts > Test Suite > Test Cases

Part 2: Test Runner: This part runs the Playwright tests.


Playwright Series

Tuesday, 19 November 2024

Playwright Post 4 - 6 Min walkthru of Playwright testing with Azure Monitor

Overview: Install VS Code and Playwright Extensions, create tests, set MFA for Canvas Apps/Power Apps, loop through Power App applications and check the home page is loading, write logs to Azure App Insights and show via the Azure Dashboard.


6 min - annotated Playwright setup and use video

====================

BDD in playwright playwright-bdd - npm

Cucumber in Playwright GitHub - dhrumil-soni-th/playwright-cucumber-learning

GitHub - mxschmitt/awesome-playwright: A curated list of awesome tools, utils and projects using Playwright

GitHub - mxschmitt/awesome-playwright: A curated list of awesome tools, utils and projects using Playwright

GitHub - mxschmitt/awesome-playwright: A curated list of awesome tools, utils and projects using Playwright



========================

Playwright Series

Friday, 8 November 2024

Playwright series - Post 2 - Refactored TS code for Consciously verify Apps in Production

Overview: Create a function with Playwright tests that loops through all my production apps, logs in, and validates the Page title load on each app's home page.

Steps:

1. Create the spec.ts code that reads app.json to loop thru and validate sites

2. Record and Store the session state for all future test runs (Used for MFA in the tests runs)

3. Create an apps.json file containing URLs to open and validate


4. After running the test, you'll see that the 3 tests were completed successfully. In my case, there were 2 Power Apps with MFA enabled and an anonymous public website that had been checked.

Optional
Create short cuts to run your tests using PowerShell
PS C:\repos\PW> npx playwright test -g "Prod-CanvasApps" --project=chromium --headed

Next Steps:

Run continuously using the Azure Playwright Service.

=========================

Playwright Series

Playwright Post 1 - Overview of E2E testing using Playwright

Playwright Post 2 - Continuously Test/Monitor Canvas apps and website with MFA enabled (this post)

Playwright Post 3 - Add App Insights logging inside your Playwright tests 

Playwright Post 4 - 6 Min walkthru of Playwright testing with Azure Monitor

Playwright Post 5 - Understanding how playwright works

Playwright Post 6 - Unattended testing when secured with MFA 


Other Posts

Upgrading two C# Blazor web applications and verifying using Playwright - super fast 

Mendix - Part 2 - Diving deeper (E2E automation testing of Mendix using Playwright)

Low-code testing with playwright walkthru

Continiously Monitor Apps using Playwright with TS

Testing Canvasa apps with Playwright using C# (rather use TS, it's better)

Wednesday, 6 November 2024

Fix links within Pdf files when moving from a File share to web hosting

Overview: Build a console to help migrate more than 80k PDF document internal links. The client used a DFS SMB file share to hold index PDFs and multiple documents that needed to be moved to a SharePoint document library.

Hypothesis: Loop through all PDFs in a folder; if there are links, identify the file server links and convert them to web links so they work in the new SharePoint document library.  Various tools were identified as possible solutions, but came up short in the migration.  Two good tools are Replace Magic & PDF-XChange Editor.

Resolution: Below is the C# code I wrote to update the links in VS Code.  The debugger was helpful because there were many different link types across the plethora of PDFs.


C# Code

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Annot;
using iText.Kernel.Pdf.Action;
using iText.Bouncycastle.Crypto;  // pdf fails at runtime periodically without the directive
using System.Text.RegularExpressions;
class Program
{
    static void Main(string[] args)
    {
        string folderPath = @"C:\Users\PaulBeck\Downloads\Software\LinkConvert\ConvertLinksCsharp\"; // Replace with your folder path          
        Console.WriteLine("Please enter a folder Path: e.g. " + folderPath);
        string inputPath = Console.ReadLine();        
        Console.WriteLine("Last Path: e.g. Childfolder2");
        string inputPathVol = Console.ReadLine();
        if (inputPath.Length>5)  {
            folderPath = inputPath;   }
        string[] pdfFiles = Directory.GetFiles(folderPath, "*.pdf");
        foreach (string file in pdfFiles)
        {
            Uri fileUri = new Uri(file);
            string directory = Path.GetDirectoryName(file);
            string filename = Path.GetFileNameWithoutExtension(file);
            string extension = Path.GetExtension(file);           
            string newFilename = $"{filename}_new{extension}";  // Create the new filename
            string newFilePath = Path.Combine(directory, newFilename); // Combine the directory and new filename to form the new URL
            UpdatePdf(fileUri.AbsoluteUri,newFilePath, inputPathVol);
        }
    }
private static void UpdatePdf(string inputFilePath, string outputFilePath, string lastPathPart)
{
    var varInnerName = "";
    PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputFilePath), new PdfWriter(outputFilePath));
        for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++)        // Iterate through the pages
        {
            var page = pdfDoc.GetPage(i);
            var annotations = page.GetAnnotations();
            foreach (var annotation in annotations)            // Iterate through the annotations
            {
                if (annotation.GetSubtype().Equals(PdfName.Link))
                {
                    var linkAnnotation = (PdfLinkAnnotation)annotation;
                    var action = linkAnnotation.GetAction();                                                        
                    if (action is PdfDictionary dictionary)
                    {
                        foreach (var key in dictionary.KeySet())
                        {
                            var value = dictionary.Get(key);
                            Console.WriteLine($"{key}: {value}");
                            var varPdfNameF = dictionary.Get(PdfName.F);
                            if (varPdfNameF is PdfDictionary varF2Dict)      {
                                varInnerName = varF2Dict.Get(PdfName.F).ToString();  }
                        }
                    }
                    else
                    {   Console.WriteLine("No URL found.");    }  
if (action != null && (action.Get(PdfName.S).Equals(PdfName.GoToR) || action.Get(PdfName.S).Equals(PdfName.Launch)))                
                      {
                        var varF = action.GetAsString(PdfName.F)?.ToString() ?? "";
                        var uri = $"https://radimaging.sharepoint.com/sites/Documents/Standards/{lastPathPart}/{varInnerName}";          
                       string pattern = @"\.\./";
                       if(uri.Contains("../"))    // string cleanUrl1 = Regex.Replace(uri, pattern, string.Empty);
                       {          
                        uri = $"https://radimaging.sharepoint.com/sites/Documents/Standards/{varInnerName}";
                        uri= Regex.Replace(uri, pattern, string.Empty);                       
                       }
                        var newAction = PdfAction.CreateURI(uri);
                        if (varF.Length > 20)      {
                            newAction = PdfAction.CreateURI(varF);     }
                        linkAnnotation.SetAction(newAction);
                    }           
                }
            }
        }
        pdfDoc.Close();
        Console.WriteLine("PDF links updated successfully!");
    }
}


Quick way to use the PDF X-Change Editor tool to change links.

Example of how to correctly set internal links within a pdf:


Example of how to set links to pages or files on the Internet/extranet:


Update Nov 2025: User Playwright MCP to download an index pdf, and then download or open files and pages to validate the links worked.  Updated the index pdf using C# Console built using Github Copilot (GHCP) and updated into SharePoint using MS Graph the updated fixed pdf.

Wednesday, 31 July 2024

Low Code testing with Playwright - 1. Intro Exercise (15 min)

Exercise 1.  Install and setup you first Playwright Test

1. Verify VS Code is installed 
2. Ensure the Microsoft Playwright Extension is installed (use the default language TypeScript)
 
3. Create a folder using Windows Explorer as shown here: C:\Users\paulb\source\repos\Playwright\Mendix

4. Open the folder in VS Code and ensure the project is initialised C:\Users\paulb\source\repos\Playwright\Mendix> npm init playwright@latest --yes -- --quiet --browser=chromium --browser=webkit

5. Verify your screen looks similar to this...




Exercise 2.  Record and run your first Playwright test

1. On the "Testing" area, select "Record new"


2. The recorder opens, type in a url in my case I used "https://www.paulbeck.co.uk"


3. Click and assert text exists on the page

4. Stop the recorder and close the browser.

5. Run the test, as shown below, validate the result

Playwright Series

Thursday, 7 December 2023

Upgrading Two web applications and verifying using Playwright - super fast

Overview: A couple of my internal recent projects all clipped together to allow my to upgrade two websites to .NET 8. And verify the upgrade and commit to source control in a regulated controlled manor and it took less than 30 minutes.

I download the latest version of Visual Studio 2022 Enterprise edition and noticed an option to upgrade my .NET projects, so I clicked it. The .NET Upgrade Assistant downloaded and installed upgrade in Visual Studio.  The upgrade is done using a vsix template import: Microsoft.NET.UpgradeAssistant.vsix

I thought I may as well upgrade my two current .NET projects:

1. App Service on Azure running Blazor .NET 6, using TFS for source control and published using my Visual Studio profile.

Once the upgrade was applied took 10 seconds and i chose LTS  .net8, I published.  Code is still not checked in.  I has a quick look and the  app loos to be running correctly in a browser. 

2. Static Web App hosting a Blazor .NET 6 connected to Github and published as a gated checkin using git Actions. Upgrades, and when I checked into the main github branch, the action fired and upgraded the static web app.

Verify Build:

So I had checked both apps where running using the good old open in a browser and look around.  A few days ago I was playing with Playwright and my testing covered validating the App Service website can send email, is running and text is visible, it also checks a Mendix low code website and lastly it looks at the Static Web App to validate it is service pages.  I did this is Visual Studio Code. 

The tests tell me both applications are running, verifies WAG compliance on 1 app and also checks a Mendix website is running.

Summary:  By re-using the test project I could quickly verify the project upgrades and the first project still requires a commit to complete but it is way safer than my direct to production gated checking done on the static web app.


Mendix - Part 2 - Diving deeper (E2E automation testing of Mendix using Playwright)

Mendix Series

1.  Overview of Mendix 

2. Mendix - Part 2 - Diving deeper (this post)

AI with Mendix (current version Mendix 10.5.x):

  1. Logic bot - recommends what you are likely to do, like a copilot as you go along building the app
  2. Performance bot - shows redundancies, recommends performance improvements 
  3. Chatbot in beta

Playwright is a good UI testing tool for Mendix:

For more advanced applications, Playwright is a good testing framework that can help developers know their code is running end-to-end, useful for monitoring applications and behaviour, and also can be used as part of the CI process to validate Mendix end user accessibility as shown in this mp4 (7 minutes - good video).

mp4 walking thru testing a Mendix site, including WCAG accessibility

WCAG accessibility testing in Playwright starts at min 5:25. Build in WCAG testing to your playwright tests> npm install @axe-core/playwright

Thoughts:

Mendix Tip: I needed to change from US format to UK date time format:
The community has the answer: Mendix Forum - Question Details

Mendix Series

1.  Overview of Mendix 

2. Mendix - Part 2 - Diving deeper (this post)

3. Extensibility for Mendix Studio 

4. Building a Mendix Widget for the Mendix marketplace (Convert text to Audio using Azure AI)

5. Mendix Tips & Thoughts



Playwright Series

Tuesday, 5 December 2023

Playwright series - Post 1 - Overview of E2E testing using VS Code for Low Code

Setup: I have installed Node 20.100.0 and the VS code extension for Playwright.  The installation and getting started guides are straightforward and of a high quality.  https://playwright.dev/docs/intro  I am running on Windows 10 Surface 4 with 16GB.  I use TypeScript (ts) as the default, and the recording mechanism works well with ts.  Previously, I used C# as my language of choice, but it is easier to maintain, and there is no need for complex logic/functions in end-to-end (e2e) UI testing.  New features always come out in TS/JS first.

Thoughts:  Postman is easy to use, fast, configurable and flexible.  UI e2e testing allows me to know my app/sites are working as expected.  Manual testing is time consuming, and amending automated tests can be hard.

Setup Reminder:

1. Install the Playwright extension using VSCode (once at initial setup)

2. Open a new folder in VSCode, and open the "Command Pallette" (once for each new project)

>Install Playwright

These are the defaults and will use TypeScript as the base language, stick to this it is the simpliest.  VSCode builds the default file scaffolding as shown above


3. Create your first New Playwright UI Test:

3.1. Record new


3.2. Enter a URL in the recorder browser, and click around (optional add Asserts) 



3.3. Save the Test

3.4. Execute the test

The Green tick can be used to quickly run the test locally.  In the "Test Results" terminal, you can see the same test was run 3 times, my configuration is set to test Chrome, Firefox and webkit.

Why Playwright?

  • Easy to understand/follow,
  • Easy to record,
  • Open source, 
  • No paid licencing, 
  • Faster than Selenium,
  • Various coding languages supported (bindings for C#, Python, Java, JS, TypeScript),
  • UI verification using screenshots and AI to minimize flakiness/static DOM reliance,
  • The ability to debug and trace is strong,
  • Can do API testing,

Possible Playwright UI testing Layers: 

  1. Full regressions go into detail and run in Chrome, Firefox, WebKit and specified devices 
  2. Check-in tests are comprehensive on a single browser for code check-ins
  3. Continuous testing: Record logging in, reading from a database, and calling an API. You can write to logs, e.g., Dynatrace, Azure Monitor, and SolarWinds using APIs. Doing this every 5 minutes will tell you at a high level if the service and its dependencies are running and if there is a performance change.
  4. A developer can write detailed local tests when working in an area and reuse them if he comes back and changes any code.

Testing Challenges:

Unit testing is a challenge in low code - while they are fast and ideal for C# or code, not easy to implement for Low code.  Their is a new beta feature for component testing in Playwright, i don't think it adds value.  API Testing - I use Postman for API testing including controlling my CI.  Low code automation testing is hard in the Power Platform, E2E playwright testing in context works pretty well.  API's/ network traffic needs to be mocked.

Challenger products:

  • Selenium - QA's highly skilled here
  • Cypress - Devs tended to use this over Selenium
  • Specific products like Power Platform Test Studio and ...
  • I also like BrowserStacks low code testing, especially if no CI/CD and can manage from here and use different low code technology.  

Summary: Generally, I'd go for Playwright over all the others. 

=========================

Playwright Series

Playwright Post 1 - Overview of E2E testing using Playwright (this post)

Playwright Post 2 - Continuously Test/Monitor Canvas apps and website with MFA enabled 

Playwright Post 3 - Add App Insights logging inside your Playwright tests 

Playwright Post 4 - 6 Min walkthru of Playwright testing with Azure Monitor

Playwright Post 5 - Understanding how Playwright works

Playwright Post 6 - Unattended testing when secured with MFA 


Other Posts

Upgrading two C# Blazor web applications and verifying using Playwright - super fast 

Mendix - Part 2 - Diving deeper (E2E automation testing of Mendix using Playwright)

Low-code testing with playwright walkthru

Continiously Monitor Apps using Playwright with TS

Testing Canvasa apps with Playwright using C# (rather use TS, it's better)