August 24, 2026

Setting up a CI/ CD pipeline with GitLab: Quality, Test and Report

So far, we have reviewed how to review code with ES Lint + Prettier and Typecheck, how to set up and run smoke tests, how to run all Playwright + TypeScript tests, and reviewed the HTML report of results.

In this post, we are going to set up a three stage GitLab CI/ CD pipeline that will run against every merge request: 
  •  Quality (lint, typecheck, prettier)  --> Test ( smoke + regression ) --> Report ( Downloadable )
GitLab reads .gitlab-ci.yml from the repository root and turns it into a pipeline, a set of jobs, grouped into stages, running whenever you push a change to a repository. 

Stages run one after another, and jobs within a stage run in parallel.  If one stage fails, the stages after it are skipped. 

This begs the question: What is GitLab? What is CI/ CD? Or a pipeline? Or a merge request? 

What is GitLab? 

GitLab began in 2011 as a side project by Ukrainian programmer Dmytro Zaporozhets, built to help developers work together on code more easily. Over time, it grew into a large open-source DevOps platform. More than just storing code, it handles code reviews, CI/CD (continuous integration and continuous delivery), and package registries. A company called GitLab Inc. was eventually created to turn the project into a commercial product.

What makes GitLab different from tools that only host Git repositories (like a basic Git server) is that it bundles the entire software delivery process into one application. This includes:

  • Merge requests – GitLab's term for proposing and reviewing code changes before they're merged into the main codebase (similar to a "pull request" in GitHub)
  • Issue tracking – a built-in system for logging bugs, tasks, and feature requests
  • Pipelines – automated workflows that build, test, and deploy code whenever changes are pushed

So instead of stitching together separate tools for version control, testing, and deployment, GitLab gives you all of it in one place.

Isn't That Just GitHub? 

According to GitLab's "What are the fundamental differences between GitLab and GitHub", "GitHub's security scanning, AI, and advanced CI/CD are native but sold as separate paid add-ons on top of the base platform price [...] GitLab puts planning, source code, CI/CD, security, and deployment into a single application with one permission model, one audit trail, and shared analytics. That means fewer tools to run, fewer integrations to maintain, and one place to apply policies and AI across the whole lifecycle".

GitLab calls all the extra stuff you need to purchase from GitHub a "toolchain tax". 

What is CI/ CD?


"CI/CD stands for Continuous Integration and Continuous Delivery (or Deployment). It's a DevOps practice that automates building, testing, and deploying code changes, enabling faster and more reliable software releases.

"CI/CD is best explained as an automated workflow that replaces manual steps with pipelines that build, test, and deploy software reliably.

"CI/CD falls under DevOps (the joining of development and operations teams) and combines the practices of continuous integration and continuous delivery. CI/CD automates much or all of the manual human intervention traditionally needed to get new code from a commit into production, encompassing the build, test (including integration tests, unit tests, and regression tests), and deploy phases, as well as infrastructure provisioning.

"With a CI/CD pipeline, development teams can make changes to code that are then automatically tested and pushed out for delivery and deployment. Get CI/CD right and downtime is minimized and code releases happen faster" - GitLab.com / What is CI / CD?

What are CI/ CD Pipelines?


"A CI/CD pipeline is an automated process utilized by software development teams to streamline the creation, testing and deployment of applications.

"CI represents continuous integration, where developers frequently merge code changes into a central repository, allowing early detection of issues. CD refers to continuous deployment or continuous delivery, which automates the application's release to its intended environment, ensuring that it is readily available to users. This pipeline is vital for teams aiming to improve software quality and speed up delivery through regular, reliable updates.

"Integrating a CI/CD pipeline into your workflow significantly reduces the risk of errors in the deployment process. Automating builds and tests ensures that bugs are caught early and fixed promptly, maintaining high-quality software". - GitLab.com / What is CI / CD?

Just like GitHub, GitLab is free to join, hoping people will use the platform and decide to subscribe for more of its services. 

With GitLab you can take your changes you want to make to the codebase of the code repository, try to commit the changes, and make a request to merge the changes into the main branch. 

You can set up the CI/ CD pipeline that before a senior developer looks at your merge request to see if it can be approved, the merge request gets tested right when it gets created. 

How Do You Create a Merge Request?


Let's say you want to make a change to a code repository to bun-create-playwright

First, if you haven't already, you need to pull down the code repo:
  • Do you have Git? Open PowerShell or the Terminal, whatever is your Command Line Interface for the PC or the Mac, and run: git --install
  • If you do not have git, install it on you Windows machine or MacBook.
  • Get the code repository: git clone git@gitlab.com:tjmaher/bun-create-playwright.git
Already downloaded the repo, and want to make sure you have the latest version?
  • git fetch origin
  • git checkout main
  • git pull origin main
Ready to make some updates? 
  • git checkout -b feature/my-new-change
Then make your changes. After that is done, add your changes and create a commit for your changes:
  • git status // All your files you made changes to are listed in red, since they are unstaged.
  • git .add 
  • git status // All your changes are now listed in green. They are staged. 
  • git commit -m "This is my commit!"
 Changes all set? Push the changes to your remote repo:
  • git push -u origin features/my-new-change
Now, you will see a URL pointing exactly to the link where you can see your commit in GitLab. Select the button, "Create Merge Request".

Once you that, the Merge Request will be created, and will be run automatically on the GitLab CI/ CD pipeline.. once we create one. 

Create the Configuration File For a CI/ CD Pipeline

Here, we are going to start reviewing the sample .gitlab-ci.yml file I created for Bun-Create-Playwright, the configuration file used when creating a new pipeline that will process the changes we have made to the code base. 

bun-create-playwright / .gitlab-ci.yml
stages:
  - quality
  - test
  - report

For any CI / CD pipeline created when a merge request is pushed, we are setting up four stages:
  • Quality: Where we check the format using Prettier, run the linter allowing no warnings to sneak by, and run the TypeScript compiler to do type checking. This stage takes seconds to run. 
  • Test
    • We run just the one smoke test on Chromium, checking that we can log into the Login page.
    • Is the smoke test successful? We then will run ALL the tests, positive and negative, on every platform, on Chrome, Firefox, and WebKit / Safari. 
  • Report: Create a report we can download and examine. 

Hidden Jobs: The Quality Template

If we take a GitLab job, and add a dot to the name, it becomes a "hidden" job. Let's say that you have a stage called QUALITY, and you have a substage which checks the format of the code, a substage that runs a linter on the code, and a substage that type checks the code.

Each substage might need to have the same things added to it, such as using the same pre-configured Docker image for bun, version 1.3, so you don't have to manually install bun, its version managers or system libraries. 

Or you could take the lockfile as is, produced when dependencies are installed, and use that same exact version on all three substages. 

That ,bun_quality could act as a template that could be extended into all three substages. 

.bun_quality:
  image: oven/bun:1.3
  before_script:
    - bun --version
    - bun install --frozen-lockfile


Docker is a tool that packages your code and everything it needs -- like libraries and system tools -- into a single box called a container. This container runs the exact same way on your laptop, your teammate's computer, and the cloud server, fixing the classic "it works on my machine" problem

Docker Hub is a public cloud-based registry service and community library of Docker images. 

Bun, the package manager, has a Docker Hub it has dubbed "oven". Here, we are going to be using the Docker image of Bun version 1.3. 

Before we run any of the substages -- format, lint, or typecheck -- we will in all stages check the version of bun used, print it out to the log file, then install bun using the Bun 1.3 Docker image, from a frozen lockfile. 
  • A lockfile is a "file that lists the direct and indirect dependencies of an application and their version numbers. Its purpose is reproducibility, to ensure anyone installing the application’s dependencies gets the exact same versions". ( GitLab / Terminology  Lockfile )
  • By installing a frozen lockfile, we are locking down all package dependencies in our jobs so we will use the same exact version in all three cases. If the lock file is out of sync from package.json, we will have it fail instead of it silently updating. 
By having it frozen, we can guarantee reproducible builds and catch cases where a dependency was added/changed without committing the updated lockfile.

The Quality Stage


Now that we set up the quality template, we can use it for the substages: format, lint, and typecheck.

format:
  extends: .bun_quality
  stage: quality
  script:
    - bun run format:check

lint:
  extends: .bun_quality
  stage: quality
  script:
    - bun run lint:ci

typecheck:
  extends: .bun_quality
  stage: quality
  script:
    - bun run typecheck

Need to add another part to the quality stage? You can just declare it, extending the same template, designating the stage, and adding the script you want to run.

  • Format:check throws an error when Prettier finds a formatting style error while running the script: "prettier --check ."
  • Lint:ci uses ES Lint to see if the code has an errors with the script: "eslint . --max-warnings 0"
  • Typecheck uses the TypeScript compiler to see if there an errors, running: "tsc --noEmit"
This CI Pipeline will execute these three stages. Any errors detected? The build pipeline will be halted. 

Introducing: The Official Playwright Docker Image

This GitLab pipeline when running tests, will use the official Docker image that Microsoft has released to run Playwright tests: mcr.microsoft.com/playwright:v1.62.1-noble

Microsoft stores its Docker images in the Microsoft Artifact Registry under the Playwright subfolder at at https://mcr.microsoft.com/en-us/artifact/mar/playwright

The Docker image uses the Ubuntu 24.04 LTS (Noble Numbat) operating system.

Hidden Jobs: The Test Template, Run on Playwright Docker


Just like the Quality stage, the Test stage will receive its own template to be used in its substages. 

And, just like the Quality stage, to make sure that each substage is on the same page, we will be using a Docker environment. The Docker image we will be using is Microsoft's official Docker environment for Playwright. 

.bun_playwright:
  image: mcr.microsoft.com/playwright:v1.62.1-noble
  before_script:
    - apt-get update && apt-get install -y unzip curl
    - curl -fsSL https://bun.sh/install | bash
    - export PATH="$HOME/.bun/bin:$PATH"
    - bun --version
    - bun install --frozen-lockfile

From Playwright.dev / Docker: "Dockerfile.noble can be used to run Playwright scripts in Docker environment. This image includes the Playwright browsers and browser system dependencies". 

Using this image in your CI/CD pipeline guarantees a stable, pre-configured, and reproducible environment for running your automated tests

After that, we are using APT, the Advanced Package Tool to refresh the container's package index, then install unzip and curl.

Once curl is installed, we download Bun's official install script (See Bun.sh / Installation ) and pipes it directly into bash to execute. The flags: 
  • -f fails silently on server errors instead of printing an HTML error page
  • -s runs silently (no progress meter)
  • -S re-enables error messages even in silent mode
  •  -L follows redirects. 
This installs the Bun binary into ~/.bun/bin.

Then we export bun's install directory to the shell's PATH for the current job session, since the install script doesn't automatically make bun available in a fresh shell (it normally edits .bashrc/.zshrc for interactive shells, which CI runners don't source the same way).

Did everything work? 
  • Print the installed Bun version to the job log. This confirms the install succeeded (the job fails fast here if bun isn't on PATH), and leaves a version record in the CI logs for debugging.
Finally we install the project's dependencies using Bun's package manager. --frozen-lockfile tells Bun to install exactly what's in bun.lock (or bun.lockb) and fail the build if the lockfile is out of sync with package.json, rather than silently updating it, which is the standard practice for CI to guarantee reproducible builds.

Whew! And this will happen on every substage in Test. 

The Test Stage

Now, we set up the test stage, first running all tests we have tagged with "@smoke". If that passes, we run ALL the tests. 

Everything we set up in .bun_playwright gets pulled right into this GitLab CI job. 

playwright:
  extends: .bun_playwright
  stage: test
  timeout: 60 minutes
  script:
    - bun run test:smoke
    - bun run test
  artifacts:
    when: always
    paths:
      - playwright-report/
      - test-results/
      - reports/
    reports:
      junit: reports/junit/results.xml
    expire_in: 30 days

  • After the clock starts, we are giving it one full hour for all the tests to run. 
Assemble the Artifacts!

Whether the jobs pass or fail, we are going to create a report so we can audit the test. We are placing the items produced in:
  • playwright-report/: This directory holds the main interactive HTML report. It includes the index.html file that lets you visually click through test suites, read error logs, and see execution timelines.
  • test-results/: This folder stores the raw individual assets captured during test execution. If a test fails, Playwright drops failure screenshots, video recordings of the browser screen, and .zip trace files (which allow you to step through the test execution like a video) into this directory
  • reports/: This is a catch-all or customized directory often used for alternative report formats. It holds JUnit XML files meant to be parsed directly by your CI platform to display a quick test summary on your pull/merge request page

The Report Stage

On the report stage, we are using a lightweight Linux container called "alpine" to execute the commands quickly. We don't need pre-installed browsers or a JavaScript runtime environment. These reports will be generated whether the tests pass or fail. 

This job will be started right after the "playwright" job finishes in the Test stage. 

report:
  stage: report
  image: alpine:latest
  when: always
  needs:
    - job: playwright
      artifacts: true
  script:
    - ls -la playwright-report/ test-results/ reports/junit/ || true
  artifacts:
    when: always
    paths:
      - playwright-report/
      - test-results/
      - reports/
    reports:
      junit: reports/junit/results.xml
    expire_in: 30 days


Next, we have the script, where we are going to list the contents of our test results directory. The "-la" will even list the hidden directories that might exist. 

Even if one of the directories do not exist, we still want to carry on, which is why we are appending "OR TRUE" to the script. 

Finally, we add the reports and XML file to GitLab's servers. 

View The Results


There you have it! Now, when you push changes, your code can be checked for quality, and you can make sure the tests all actually run. 

Each code change, each merge request, generates a new pipeline. You can view it at https://gitlab.com/tjmaher/bun-create-playwright/-/pipelines


You can also download the reports:


Test Report Artifacts

  • report:archive: Contains the full, human-readable HTML test reports (like Allure, if set up, or Playwright's native HTML report) compressed into a zip archive.
  • report:junit: Contains a structured XML file in the JUnit format used by CI/CD platforms to parse, count, and display test success rates directly in the pipeline UI.

Playwright Specific Artifacts

  • playwright:archive: Stores heavy debugging assets generated during test failures, such as recorded videos, browser screenshots, and .zip trace files that you can load into the Playwright Trace Viewer.
  • playwright:junit: Holds the specific JUnit-formatted XML results generated directly by the Playwright test runner (@playwright/test) during execution.
You can also drill down into the pipeline to see each stage's results. 


With each stage, you can drill down to see the log files for that stage. 

And, last of all, you can download an HTML version of the report, in the archive of artifacts.


That's how you set up a GitLab CI/ CD pipeline! 

Next, we are going to look into manually kicking off a job, viewing a report on GitLab Pages. 







Until then, Happy Testing!

-T.J. Maher
Software Engineer in Test

BlueSky | YouTubeLinkedIn | Articles

August 19, 2026

How to Configure Playwright Test to run smoke tests, headed tests, and debug versions through scripts in package.json

Earlier, we went over how we could create scripts in the package.json file of our Playwright framework to add typechecking, linting, and formatting your code with prettier
With this post, we will explore how the built-in test runner for Playwright Test can run headed tests, debug versions of tests, and smoke tests.

... and shortcuts for all of these can be set up in the scripts in your package.json! If you are using "bun" as a package manager, as we are in bun-create-playwright, just type out "bun run", a space and then the shortcut such as: bun run test

package.json
"scripts": {
    "test": "playwright test",
    "test:headed": "playwright test --headed",
    "test:trace": "playwright test --trace on",
    "test:chromium": "playwright test --project=chromium",
    "test:firefox": "playwright test --project=firefox",
    "test:webkit": "playwright test --project=webkit",
    "test:smoke": "playwright test --project=chromium --grep '@smoke'",
    "test:flaky": "playwright test --project=chromium --repeat-each=20",
    "test:ui": "playwright test --ui",
    "test:debug": "playwright test --debug",
    "test:failed": "playwright test --last-failed",
    "test:login": "playwright test tests/login.spec.ts",
    "test:secure-area": "playwright test tests/secure-area.spec.ts",
    "report:list": "playwright test --reporter=list",
    "report:line": "playwright test --reporter=line",
    "report:dot": "playwright test --reporter=dot",
    "report:blob": "playwright test --reporter=blob",
    "report": "playwright show-report",
    "codegen": "playwright codegen",
    "lint": "eslint .",
    "lint:ci": "eslint . --max-warnings 0",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "format:debug": "prettier --check . --log-level debug",
    "format:diff": "prettier --list-different",
    "typecheck": "tsc --noEmit"
  },

Do you need to really set up shortcuts like these? Certainly not! But it is easier than typing out: bunx playwright test --project=chromium --grep '@smoke'.

Feel free to name these commands anything you want! 

August 16, 2026

Implementing Page Objects in Playwright

Picture a login screen, such as The-Internet / Login


On this LoginPage, there is:
  • a heading: Login Page
  • a user name textbox with the label, "Username"
  • a password textbox with the label, "Password"
  • a login button, with the role of a button, and the name of "Login"
  • a flash message that appears if you enter invalid credentials such as "NotAUser" and "NotAPassword".
If you successfully log in with "tomsmith" and "SuperSecretPassword!, there is a SecureArea:
  • a heading: "Secure Area"
  • a flash message "You logged into a secure area!"
  • a Logout button. 
Sure, you could interact with each web element in your test... but what if the username text box locator changes? You would have to update multiple tests every time the element changed. 

... Instead, you could place it in a Page Object, something that Playwright handles well!

"A page object represents a part of your web application. An e-commerce web application might have a home page, a listings page and a checkout page. Each of them can be represented by page object models.

"Page objects simplify authoring by creating a higher-level API which suits your application and simplify maintenance by capturing element selectors in one place and create reusable code to avoid repetition".

Using Playwright's Built-In Test Runner? Or Something Else?


You may have noticed in https://playwright.dev/docs/pom that there are two different styles of page objects. One for "Test". One for "Library". 
  • Test: If you are writing actual Playwright test suites, and Playwright's built in test runner, use the Test section as a guide when creating page objects. 
  • Library: If you are integrating Playwright into an existing test framework such as Jest or Cucumber and just want browser automation, instead of having pre-built page fixtures, etc, you can use this format. 

August 14, 2026

How Playwright Frameworks get configured with playwright.config.ts

When we installed bun, a new package manager owned by Anthropic, then ran "bun create playwright", a new automation framework was stood up, along with sample tests, and a Playwright configuration file. In this post, we will be examining the file generated: playwright.config.ts.  

Personally, I find the pre-generated file very hard to scan... there are so many options and documentation in the comments, it is difficult for me to focus on the code. Let's examine just the code generated below. If you need to see the whole file, you can see it here: https://playwright.dev/docs/test-configuration

Playwright.dev / Configuration mentions, "Playwright has many options to configure how your tests are run. You can specify these options in the configuration file". 

August 10, 2026

Running Tests with Playwright Test Explorer and Generating Tests with Codegen

Finding the best locator for a web element can be a hassle:
  • Right clicking on an element in Google Chrome. Inspecting the element. Going to Chrome Developer Tools. Try to decide what to do if there isn't a clear test id. 
Playwright comes with a built in code generator where it can built out a rough draft of a test while you interact with a website. "Playwright will look at your page and figure out the best locator, prioritizing role, text and test id locators. If the generator finds multiple elements matching the locator, it will improve the locator to make it resilient that uniquely identify the target element", according to Playwright.dev / Test Generator.

Do you have the Integrated Development Environment (IDE) by Microsoft, VS Code? You can get it at the Visual Studio Marketplace

Playwright Test Explorer


After installation, you will see a beaker icon in your VS Code left navigation menu. Selecting that, you can see your tests, such as the default ones Playwright automatically adds when it is installed: 


Checking code with lint, formatting it with prettier

Now that we've installed bun, Anthropic's package manager, scaffolded a Playwright framework and closely examined the results, and added typechecking with TypeScript's compiler, it's time to add ways to check the code with lint, and reformat the code with prettier

We will be using:
  • ESLint, as the static-analysis tool to review the code without running it. Little bits of fluff -- like syntax errors, structural bugs, anti-patterns, and code style violations -- can collect on your code, so it helps to run a linter to help catch it all, such as ESLint. There is also a linter,  eslint-plugin-playwright, for Playwright tests.
  • Prettier enforces a consistent code style across your entire codebase. Because ESLint and Prettier can conflict, we will be using Prettier's eslint-config-prettier, which turns off all rules that are unnecessary or might conflict with ESLint.

What is a Linter? 

According to the Wikiwand entry for Lint, "Stephen C. Johnson, a computer scientist at Bell Labs, came up with the term 'lint' in 1978 while debugging the yacc grammar he was writing for C and dealing with portability issues stemming from porting Unix to a 32-bit machine. The term was borrowed from lint, the tiny bits of fiber and fluff shed by clothing, as the command he wrote would act like a lint trap in a clothes dryer, capturing waste fibers while leaving whole fabrics intact. The lint program was released outside of Bell Labs in Unix V7, in 1979.

"In his 1978 paper, Johnson explained his reasons for creating a new program to detect errors: '...the general notion of having two programs is a good one' because they concentrate on different things, thereby allowing the programmer to 'concentrate at one stage of the programming process solely on the algorithms, data structures, and correctness of the program, and then later retrofit, with the aid of lint, the desirable properties of universality and portability' "

August 7, 2026

Add Type Checking and TSConfig to Bun-Create-Playwright

Now that we have installed bun, Anthropic's package manager, and scaffolded a Playwright framework and closely examined the results, we are going to explore with our Bun-Create-Playwright project ways to check if our code is correct. 

The first method we will be exploring is typechecking

Why Typechecking? As the Playwright.dev / Node.js Introduction mentions:
"[...] Playwright does not check the types and will run tests even if there are non-critical TypeScript compilation errors. We recommend you run TypeScript compiler alongside Playwright.

"[...] Note that Playwright only supports the following tsconfig options: allowJs, baseUrl, paths, references and extends.

"[...] By default, Playwright will look up a closest tsconfig for each imported file by going up the directory structure and looking for tsconfig.json or jsconfig.json. This way, you can create a tests/tsconfig.json file that will be used only for your tests and Playwright will pick it up automatically".
Before we go further down this road...

What is Type Checking? 


According to Type Checking in TypeScript: A Beginners Guide, every piece of data in TypeScript is given a "type", and this "type" determines what properties the data has, and what methods are available to it. The types can be things like a Number, String, Enum, Boolean, Array, Object, Type assertions, or others.

August 6, 2026

What happens when you scaffold a Playwright framework and run installed tests using bun?

We covered in the last blog post how to install bun, a new package manager. 

In this blog post, we will look into using bun to install a new Playwright framework. 

Create the Playwright Framework


Once I installed bun on my Windows PC and was up and running I created a new folder, "bun-create-playwright".

I opened up that folder in VS Code, along with a new PowerShell terminal. In that terminal I entered:
  • bun create playwright 
This activated the interactive Playwright installer that Playwright comes with. 
  • I selected I wanted it to create for me a TypeScript project, placing the tests in the default folder, tests, but I decided not to add a GitHub Actions workflow. I wanted to experiment with using GitLab
  • I chose it to set up and install all the browsers for me... which it did... using NPX, part of Node.
Wait a second, when it comes to our Playwright framework, doesn't bun replace node?

No. Bun might be a JavaScript runtime, a package manager, and a bundler shipped as a single software tool, but in our case we are simply using it as a package manager in our Playwright framework. 

Bun works alongside Node.js in the Playwright project. We still use Playwright's test runner, a Node.js program. Bun handles installations and run tasks.

August 5, 2026

Introducing bun, a new package manager and JavaScript runtime environment

New job? New toolset to explore! In this post I'll be investigating a new JavaScript package manager and runtime environment called bun.sh

You may have noticed on Playwright.Dev's Getting Started / Installation section there are three different ways to install a ui or api test automation framework with the latest version of Playwright:
  • npm init playwright@latest
  • yarn create playwright
  • pnpm create playwright
For this blog post I'll be investigating a fourth way, the new toolset they just started using at work, bun.sh.
  • bun create playwright

What is npm, yarn, pnpm, and bun? These are called package managers.

What is a package? Developing a project, you don't have to figure out how to code everything yourself. You can include in your projects outside libraries, or "packages" of code from from the public JavaScript registry npmjs.com

The problem is that these packages then need to be downloaded, installed, managed, and updated whenever they are updated. JavaScript projects can use a package manager, such as bun, to help this process. 

When putting together a Playwright automation framework based around JavaScript and TypeScript, Playwright uses the Node.js JavaScript runtime environment, to run its test runner, execute automation scripts, and manage its browser instances.(See Nodejs.org / About )

There is a division of labor: Node.js runs these internal functions like running tests. NPM, Yarn, PNPM, and now Bun handle the packages. 

Why are there so many package managers? Each has its own specialization. The original NPM is bundled already with Node.js. Yarn is a Facebook toolset that was created when NPM was found to work too slow. PNPM was created to be smaller and therefore faster. And bun was built for quick startup and installation speed, good especially if you have a CI/ CD pipeline that has a LOT of packages to install each time the tests run.

June 29, 2026

Does giving a presentation via Zoom to the Sydney Testers Meetup make me an international speaker?

If I presentation to the Sydney Testers Meetup in Australia, from my home in the Massachusetts, through Zoom, does that make me an international speaker? [ Vote in the New Poll, on LinkedIn ]

There is still time to sign up for the event at: https://www.meetup.com/sydney-testers/events/315166776


"T.J. Maher, the former organiser at Ministry of Testing Boston, blogger and speaker, will be presenting from the US on using the Detox framework to create effective test automation frameworks for React Native applications.