forked from pacocoursey/next-themes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Playwright e2e test-suite (pacocoursey#113)
* add playwright setup * add GitHub Action to execute e2e tests * add e2e test for theme-switching and system-theme * add placeholders for forced theme and storage event e2e tests * add utility to create new browserContext for Playwright test * add test for storage events to Playwright test-suite * update system-theme test to use new helper-func * add jest config to prevent jest running playwright tests * add utility function to check theme stored in local-storage * update system theme e2e test to use new util func * rename storage-event theme test cases * add forced-theme test-cases * add e2e-test for basic theming use-cases
- Loading branch information
Showing
12 changed files
with
786 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: E2E - Test | ||
|
||
on: push | ||
|
||
jobs: | ||
setup: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
preview_url: ${{ steps.waitForVercelPreviewDeployment.outputs.url }} | ||
steps: | ||
- name: Wait for Vercel preview deployment to be ready | ||
uses: patrickedqvist/wait-for-vercel-preview@v1.2.0 | ||
id: waitForVercelPreviewDeployment | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
max_timeout: 600 | ||
test: | ||
needs: setup | ||
name: Run Playwright tests | ||
timeout-minutes: 5 | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Prepare Playwright | ||
uses: actions/checkout@v2 | ||
- uses: actions/setup-node@v2 | ||
with: | ||
node-version: "14" | ||
- run: yarn | ||
- run: npx playwright install --with-deps | ||
- name: Run tests | ||
run: yarn test:e2e | ||
env: | ||
BASE_URL: ${{ needs.setup.outputs.preview_url }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: Test | ||
name: Unit - Test | ||
|
||
on: push | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { test} from '@playwright/test' | ||
import { checkAppliedTheme, checkStoredTheme, makeBrowserContext } from './util' | ||
|
||
test.describe('forced theme test-suite', async () => { | ||
function makeForcedThemeTest(pageUrl: string, storedTheme: string, expectedTheme: string) { | ||
test( | ||
`should render forced-theme (${expectedTheme}) instead of stored theme (${expectedTheme})`, | ||
async ({ browser, baseURL}) => { | ||
const context = await makeBrowserContext(browser, { | ||
baseURL, | ||
localStorage: [{ name: 'theme', value: storedTheme }] | ||
}) | ||
const page = await context.newPage() | ||
await page.goto(pageUrl) | ||
|
||
await checkStoredTheme(page, storedTheme) | ||
await checkAppliedTheme(page, expectedTheme) | ||
}) | ||
} | ||
|
||
makeForcedThemeTest('/light', 'dark', 'light') | ||
makeForcedThemeTest('/dark', 'light', 'dark') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { checkAppliedTheme, makeBrowserContext } from './util' | ||
|
||
test.describe('storage-events test-suite', async () => { | ||
test('should switch theme if stored theme value is updated in a different tab', async ({ browser, baseURL }) => { | ||
const context = await makeBrowserContext(browser, { | ||
colorScheme: 'light', | ||
baseURL: baseURL, | ||
localStorage: [ | ||
{ name: 'theme', value: 'light'} | ||
] | ||
}) | ||
// Create page and see if stored theme is applied | ||
const page1 = await context.newPage() | ||
await page1.goto('/') | ||
await checkAppliedTheme(page1, 'light'); | ||
|
||
// Create second page and also check theme value | ||
const page2 = await context.newPage() | ||
await page2.goto('/') | ||
await checkAppliedTheme(page2, 'light') | ||
|
||
// Select theme in page2 | ||
await page2.locator('[data-test-id="theme-selector"]').selectOption('dark'); | ||
// Expect both pages to have changed theme | ||
await checkAppliedTheme(page2,'dark') | ||
await checkAppliedTheme(page1, 'dark') | ||
|
||
}) | ||
|
||
test('should apply ignored storage-event once page with forced-theme is left', async ({ browser, baseURL }) => { | ||
const context = await makeBrowserContext(browser, { | ||
colorScheme: 'light', | ||
baseURL: baseURL, | ||
localStorage: [ | ||
{ name: 'theme', value: 'dark'} | ||
] | ||
}) | ||
|
||
// Create page and see if stored theme is applied | ||
const page1 = await context.newPage() | ||
await page1.goto('/') | ||
await checkAppliedTheme(page1, 'dark'); | ||
|
||
// Create second page and also check theme value | ||
const page2 = await context.newPage() | ||
await page2.goto('/dark') | ||
await checkAppliedTheme(page2, 'dark') | ||
|
||
// Change theme on page1 and assert theme change | ||
await page1.locator('[data-test-id="theme-selector"]').selectOption('light'); | ||
await checkAppliedTheme(page1,'light') | ||
|
||
// Page 2 should not have changed theme since on page with forced theme | ||
await checkAppliedTheme(page2, 'dark') | ||
const localStorage = await page2.evaluate(() => window.localStorage) | ||
expect(localStorage?.theme).toBe('light') | ||
|
||
// Navigate to home and check if newly stored theme is now applied | ||
await page2.locator("text=Go back home").click() | ||
await page2.locator('[data-test-id="theme-selector"]').waitFor() | ||
expect(page2.url()).toBe(baseURL + '/') | ||
await checkAppliedTheme(page2, 'light') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { test} from '@playwright/test'; | ||
import { checkAppliedTheme, makeBrowserContext } from './util'; | ||
|
||
test.describe('basic theming test-suite', () => { | ||
|
||
function makeRenderThemeTest(theme: string) { | ||
test(`should render ${theme} theme`, async ({ browser, baseURL }) => { | ||
const context = await makeBrowserContext(browser, { | ||
baseURL, | ||
localStorage: [{ name: 'theme', value: theme }] | ||
}); | ||
const page = await context.newPage() | ||
|
||
await page.goto('/'); | ||
// Select dark | ||
await page.locator('[data-test-id="theme-selector"]').selectOption(theme); | ||
// Check if dark theme is applied | ||
await checkAppliedTheme(page, theme); | ||
}); | ||
} | ||
|
||
makeRenderThemeTest('light'); | ||
makeRenderThemeTest('dark'); | ||
|
||
function shouldUpdateTheme(initialTheme, targetTheme: string) { | ||
test(`should switch from ${initialTheme} to ${targetTheme}-theme`, async ({ browser, baseURL }) => { | ||
const context = await makeBrowserContext(browser, { | ||
baseURL, | ||
localStorage: [{ name: 'theme', value: initialTheme }] | ||
}); | ||
const page = await context.newPage() | ||
|
||
await page.goto('/'); | ||
await checkAppliedTheme(page, initialTheme); | ||
// Select dark | ||
await page.locator('[data-test-id="theme-selector"]').selectOption(targetTheme); | ||
// Check if dark theme is applied | ||
await checkAppliedTheme(page, targetTheme); | ||
}); | ||
} | ||
|
||
shouldUpdateTheme('light', 'dark'); | ||
shouldUpdateTheme('dark', 'light'); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { test, expect } from '@playwright/test' | ||
import { checkAppliedTheme, checkStoredTheme, makeBrowserContext } from './util' | ||
|
||
test.describe('system theme test-suite', () => { | ||
|
||
function testSystemTheme( | ||
pagePath: string, | ||
preferredColorScheme: 'light' | 'dark', | ||
expectedTheme: string | ||
) { | ||
test(`should render ${expectedTheme} theme if preferred-colorscheme is ${preferredColorScheme}`, async ({ browser, baseURL }) => { | ||
const context = await makeBrowserContext(browser, { | ||
colorScheme: preferredColorScheme, | ||
baseURL, | ||
localStorage: [{ name: 'theme', value: 'system' }] | ||
}) | ||
|
||
const page = await context.newPage() | ||
await page.goto(pagePath) | ||
|
||
await checkStoredTheme(page, 'system') | ||
await checkAppliedTheme(page, expectedTheme) | ||
}) | ||
} | ||
|
||
// Test if preferred-colorscheme works | ||
testSystemTheme('/', 'light', 'light') | ||
testSystemTheme('/', 'dark', 'dark') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Page, expect, Browser } from '@playwright/test' | ||
|
||
export async function checkAppliedTheme(page: Page,theme: string) { | ||
expect( | ||
await page.evaluate(() => document.documentElement.getAttribute('data-theme')) | ||
).toBe(theme); | ||
expect( | ||
await page.evaluate(() => document.documentElement.getAttribute('style')) | ||
).toBe(`color-scheme: ${theme};`); | ||
} | ||
|
||
export async function checkStoredTheme(page: Page, expectedTheme: string) { | ||
const localStorage = await page.evaluate(() => window.localStorage) | ||
expect(localStorage?.theme).toBe(expectedTheme) | ||
} | ||
|
||
type MakeBrowserContextOptions = { | ||
baseURL?: string, | ||
colorScheme?: 'light' | 'dark' | 'no-preference', | ||
localStorage?: {name: string, value: string}[] | ||
} | ||
|
||
export async function makeBrowserContext(browser: Browser, options: MakeBrowserContextOptions) { | ||
return await browser.newContext({ | ||
colorScheme: options.colorScheme ?? 'no-preference', | ||
storageState: { | ||
cookies: [], | ||
origins: [ | ||
{ | ||
origin: options.baseURL ?? 'http://localhost:3000', | ||
localStorage: options.localStorage ?? [], | ||
} | ||
] | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { PlaywrightTestConfig, devices } from '@playwright/test'; | ||
|
||
const config: PlaywrightTestConfig = { | ||
forbidOnly: !!process.env.CI, | ||
retries: process.env.CI ? 2 : 0, | ||
reporter: process.env.CI ? 'github' : 'list', | ||
testDir: './e2e', | ||
use: { | ||
trace: 'on-first-retry', | ||
baseURL: process.env.CI ? process.env.BASE_URL : 'http://localhost:3000', | ||
}, | ||
projects: [ | ||
{ | ||
name: 'chromium', | ||
use: { ...devices['Desktop Chrome'] }, | ||
}, | ||
{ | ||
name: 'firefox', | ||
use: { ...devices['Desktop Firefox'] }, | ||
}, | ||
{ | ||
name: 'webkit', | ||
use: { ...devices['Desktop Safari'] }, | ||
}, | ||
], | ||
}; | ||
|
||
export default config; |
Oops, something went wrong.
066ae1d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
next-themes – ./
next-themes-trm217.vercel.app
next-themes-git-main-trm217.vercel.app
next-themes-tan.vercel.app