Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
- name: Run tests defined in vitest
uses: docker://mcr.microsoft.com/playwright:v1.55.0-jammy
with:
args: npm test
args: npm test -- --project '!@primer/styled-react (vrt)'
continue-on-error: ${{ matrix.react-version == 'react-19' }}

type-check:
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/vrt-upload-snapshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Visual Regression Snapshots

on:
workflow_dispatch:
push:
branches:
- 'main'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
snapshots-runner:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2]
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- name: Set up Node.js
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Set up turbo cache
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Run tests defined in vitest
uses: docker://mcr.microsoft.com/playwright:v1.55.0-jammy
with:
args: npx vitest --project '@primer/styled-react (vrt)' --update --shard="${{ matrix.shard }}/${{ strategy.job-total }}"
- name: Upload images
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
name: vrt-snapshots-${{ strategy.shard }}
path: '**/__screenshots__/**/*-linux.png'
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ results.json
*.module.css.d.ts

# Vitest
**/__screenshots__/**
**/__screenshots__/**/*.png
**/.vitest-attachments/**

# Turbo
.turbo
68 changes: 68 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@vitest/browser": "^4.0.3",
"@vitest/browser-playwright": "^4.0.3",
"@vitest/eslint-plugin": "^1.3.24",
"@vitest/ui": "^4.0.3",
"babel-plugin-react-compiler": "^1.0.0",
"eslint": "^9.39.1",
"eslint-import-resolver-typescript": "3.7.0",
Expand Down
88 changes: 88 additions & 0 deletions packages/styled-react/config/vitest/visual/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* stylelint-disable selector-pseudo-class-no-unknown */

@import '@primer/primitives/dist/css/base/motion/motion.css';
@import '@primer/primitives/dist/css/base/size/size.css';
@import '@primer/primitives/dist/css/base/typography/typography.css';
@import '@primer/primitives/dist/css/functional/size/border.css';
@import '@primer/primitives/dist/css/functional/size/breakpoints.css';
@import '@primer/primitives/dist/css/functional/size/size-coarse.css';
@import '@primer/primitives/dist/css/functional/size/size-fine.css';
@import '@primer/primitives/dist/css/functional/size/size.css';
@import '@primer/primitives/dist/css/functional/size/viewport.css';
@import '@primer/primitives/dist/css/functional/themes/dark-colorblind.css';
@import '@primer/primitives/dist/css/functional/themes/dark-dimmed.css';
@import '@primer/primitives/dist/css/functional/themes/dark-high-contrast.css';
@import '@primer/primitives/dist/css/functional/themes/dark-tritanopia.css';
@import '@primer/primitives/dist/css/functional/themes/dark.css';
@import '@primer/primitives/dist/css/functional/themes/light-colorblind.css';
@import '@primer/primitives/dist/css/functional/themes/light-high-contrast.css';
@import '@primer/primitives/dist/css/functional/themes/light-tritanopia.css';
@import '@primer/primitives/dist/css/functional/themes/light.css';
@import '@primer/primitives/dist/css/functional/typography/typography.css';

* {
box-sizing: border-box;
}

body {
color: var(--fgColor-default);
background-color: var(--bgColor-default);
font-family: var(--fontStack-system);
line-height: var(--text-body-lineHeight-large);
margin: 0;
}

table {
/* stylelint-disable-next-line primer/borders */
border-collapse: collapse;
}

[data-color-mode='light'] input {
color-scheme: light;
}

[data-color-mode='dark'] input {
color-scheme: dark;
}

@media (prefers-color-scheme: light) {
[data-color-mode='auto'][data-light-theme*='light'] {
color-scheme: light;
}
}

@media (prefers-color-scheme: dark) {
[data-color-mode='auto'][data-dark-theme*='dark'] {
color-scheme: dark;
}
}

[role='button']:focus:not(:focus-visible):not(:global(.focus-visible)),
/* stylelint-disable-next-line selector-max-specificity */
[role='tabpanel'][tabindex='0']:focus:not(:focus-visible):not(:global(.focus-visible)),
button:focus:not(:focus-visible):not(:global(.focus-visible)),
summary:focus:not(:focus-visible):not(:global(.focus-visible)),
a:focus:not(:focus-visible):not(:global(.focus-visible)) {
outline: none;
box-shadow: none;
}

[tabindex='0']:focus:not(:focus-visible):not(:global(.focus-visible)),
details-dialog:focus:not(:focus-visible):not(:global(.focus-visible)) {
outline: none;
}

/* https://vitest.dev/guide/browser/visual-regression-testing.html#disable-animations */
*,
*::before,
*::after {
animation-duration: 0s !important;
animation-delay: 0s !important;
transition-duration: 0s !important;
transition-delay: 0s !important;
}

[data-testid='screenshot'] {
display: inline-flex;
padding: 1rem;
}
14 changes: 14 additions & 0 deletions packages/styled-react/config/vitest/visual/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {beforeEach} from 'vitest'
import './global.css'
import {updateGlobalTheme} from '../../../src/test-helpers/themes'

// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
document.documentElement.setAttribute('data-color-mode', 'auto')
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
document.documentElement.setAttribute('data-light-theme', 'light')
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
document.documentElement.setAttribute('data-dark-theme', 'dark')

beforeEach(() => {
updateGlobalTheme('light')
})
1 change: 1 addition & 0 deletions packages/styled-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@types/styled-components": "^5.1.26",
"@vitejs/plugin-react": "^4.3.3",
"babel-plugin-styled-components": "2.1.4",
"postcss-preset-primer": "^0.0.0",
"publint": "^0.3.15",
"react": "18.3.1",
"react-dom": "18.3.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {render} from '@testing-library/react'
import {describe, test, expect} from 'vitest'
import {page} from 'vitest/browser'
import {ButtonComponent as Button} from '../Button'
import {themes, updateGlobalTheme} from '../../test-helpers/themes'

describe('Button', () => {
test.each(themes)('color with sx prop (%s) @vrt', async theme => {
updateGlobalTheme(theme)

render(
<div data-testid="screenshot">
<Button sx={{color: 'rebeccapurple'}}>Click me</Button>
</div>,
)

await expect(page.getByTestId('screenshot')).toMatchScreenshot()
})

test.each(themes)('font size with sx prop (%s) @vrt', async theme => {
updateGlobalTheme(theme)

render(
<div data-testid="screenshot">
<Button sx={{fontSize: '2rem'}}>Click me</Button>
</div>,
)

await expect(page.getByTestId('screenshot')).toMatchScreenshot()
})
})
31 changes: 31 additions & 0 deletions packages/styled-react/src/test-helpers/themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const lightThemes = ['light', 'light_high_contrast', 'light_colorblind', 'light_tritanopia'] as const

type LightTheme = (typeof lightThemes)[number]

const darkThemes = ['dark', 'dark_dimmed', 'dark_high_contrast', 'dark_colorblind', 'dark_tritanopia'] as const

type DarkTheme = (typeof darkThemes)[number]

const themes = [...lightThemes, ...darkThemes]

type Theme = (typeof themes)[number]

type ColorMode = 'light' | 'dark' | 'auto'

type ThemeOptions = {

Check failure on line 15 in packages/styled-react/src/test-helpers/themes.ts

View workflow job for this annotation

GitHub Actions / lint

'ThemeOptions' is defined but never used
colorMode?: ColorMode
lightTheme?: LightTheme
darkTheme?: DarkTheme
}

function updateGlobalTheme(theme: Theme) {
if (lightThemes.includes(theme as LightTheme)) {
document.documentElement.setAttribute('data-color-mode', 'light')
document.documentElement.setAttribute('data-light-theme', theme)
} else {
document.documentElement.setAttribute('data-color-mode', 'dark')
document.documentElement.setAttribute('data-dark-theme', theme)
}
}

export {themes, updateGlobalTheme}
2 changes: 1 addition & 1 deletion packages/styled-react/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ export default defineConfig({
test: {
name: '@primer/styled-react (node)',
environment: 'node',
exclude: ['src/**/*.browser.test.?(c|m)[jt]s?(x)'],
exclude: ['src/**/*.browser.test.?(c|m)[jt]s?(x)', 'src/**/*.visual.test.?(c|m)[jt]s?(x)'],
},
})
Loading
Loading