What is GitHub Actions Matrix Strategy?
The GitHub Actions matrix strategy is a powerful feature that allows you to run the same job across multiple combinations of variables — like environments, operating systems, or software versions — without duplicating code. It’s ideal for scenarios such as:
- Testing across different browser environments
- Running code against multiple versions of a language
- Deploying across multiple platforms (e.g., Android and iOS)
By using a strategy.matrix
section in your workflow, you can define all the variations you want to test or execute. GitHub will then automatically create a job for each combination. This not only helps keep workflows clean and scalable, but also provides a clear view of which combinations succeed or fail.
Here’s a basic example:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [16, 18]
This configuration will run four jobs in parallel:
- Ubuntu + Node 16
- Ubuntu + Node 18
- Windows + Node 16
- Windows + Node 18
Learn more from GitHub’s official documentation
Cross-Browser UI Testing with GitHub Actions Matrix Strategy
When building UI automation workflows, one of the most common challenges is ensuring consistent functionality across different browsers. Initially, I handled this by creating separate GitHub Actions YAML files for each browser:
ui_chrome_pytest.yml
ui_firefox_pytest.yml
Each file had almost identical steps, with only minor differences.
🔍 Key Differences in the Old Files
ui_chrome_pytest.yml
manually installs Google Chrome and ChromeDriverui_firefox_pytest.yml
usesbrowser-actions/setup-firefox
to install
Firefox and GeckoDriver
- The
pytest
command uses--browser chrome
in one,--browser firefox
in the other - Both upload the same artifacts, which could overwrite each other
This setup worked, but had several downsides:
- ❌ Duplication of logic — every change had to be applied in multiple files
- ❌ Error-prone — it’s easy to forget updating one of them
- ❌ Not scalable — adding another browser meant copying more of the same logic
The Solution: Matrix Strategy
So, to eliminate the duplication and better manage different browser setups, I leveraged the GitHub Actions matrix strategy. This approach allows each browser to be tested in parallel, using a single, unified workflow file.
I created a new workflow called:
ui_cross_browser_test.yml
name: UI Automation Tests
on:
pull_request:
branches:
- main
jobs:
build_and_test:
runs-on: ubuntu-latest
strategy:
matrix:
browser: [chrome, firefox]
steps:
- name: Checkout resume repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install dependencies and build
run: |
yarn install
yarn build
- name: Start the application
run: |
yarn start &
env:
PORT: 3000
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Chrome and ChromeDriver
if: matrix.browser == 'chrome'
run: |
sudo apt update
sudo apt install -y wget gnupg
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
CHROMEDRIVER_VERSION=$(curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
wget https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin/chromedriver
sudo chmod +x /usr/local/bin/chromedriver
- name: Set up Firefox and GeckoDriver
if: matrix.browser == 'firefox'
uses: browser-actions/setup-firefox@latest
- name: Clone the test repository
run: |
git clone https://github.com/serhatozdursun/serhatozdursun-ui-tests.git
env:
GITHUB_TOKEN: ${{ secrets.UI_TEST_TOKEN }}
- name: Install Python dependencies
working-directory: serhatozdursun-ui-tests
run: |
pip install -r requirements.txt
- name: Run tests on ${{ matrix.browser }}
working-directory: serhatozdursun-ui-tests
id: run_tests
run: |
pytest --browser ${{ matrix.browser }} --base_url http://localhost:3000 --html=reports/html/report.html --junitxml=reports/report.xml
- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: html-report-${{ matrix.browser }}
path: serhatozdursun-ui-tests/reports/html
retention-days: 5
continue-on-error: true
- name: Upload XML report
if: always()
uses: actions/upload-artifact@v4
with:
name: xml-report-${{ matrix.browser }}
path: serhatozdursun-ui-tests/reports/report.xml
retention-days: 5
continue-on-error: true
Before vs After
Final Thoughts
Using GitHub Actions’ matrix strategy is a game-changer for cross-browser testing — or any testing that requires variation in environments, tools, or platforms.
If you’re still duplicating workflow files for minor differences, it’s time to simplify and scale.