Skip to content

Commit

Permalink
(@wdio/cli): add support for snapshot testing (#12058)
Browse files Browse the repository at this point in the history
* (@wdio/cli): add support for snapshot testing

* update unit tests

* add docs

* note that there is only one snapshot per capability

* skip svelte e2e tests due to #12056

* fix e2e test
  • Loading branch information
christian-bromann committed Jan 22, 2024
1 parent aa0eb24 commit 828c757
Show file tree
Hide file tree
Showing 29 changed files with 404 additions and 51 deletions.
22 changes: 22 additions & 0 deletions e2e/browser-runner/__snapshots__/lit.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Snapshot v1

exports[`Lit Component testing > should support snapshot testing 1`] = `"<simple-greeting name="WebdriverIO"></simple-greeting>"`;

exports[`Lit Component testing > should support snapshot testing 3`] = `
{
"parsed": {
"alpha": 0,
"hex": "#000000",
"rgba": "rgba(0,0,0,0)",
"type": "color",
},
"property": "background-color",
"value": "rgba(0,0,0,0)",
}
`;

exports[`Lit Component testing > should support snapshot testing 5`] = `
{
"foo": "bar",
}
`;
3 changes: 3 additions & 0 deletions e2e/browser-runner/__snapshots__/react.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Snapshot v1

exports[`React Component Testing > supports snapshot tests 1`] = `"<div><button>Current theme: light</button></div>"`;
30 changes: 30 additions & 0 deletions e2e/browser-runner/lit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,36 @@ describe('Lit Component testing', () => {
expect(await innerElem.getText()).toBe('Hello Sir, WebdriverIO! Does this work?')
})

it('should support snapshot testing', async () => {
render(
html`<simple-greeting name="WebdriverIO" />`,
document.body
)

const elem = $('simple-greeting')
await expect(elem).toMatchSnapshot()
await expect(elem).toMatchInlineSnapshot(`"<simple-greeting name="WebdriverIO"></simple-greeting>"`)
await expect(elem.getCSSProperty('background-color')).toMatchSnapshot()
await expect(elem.getCSSProperty('background-color')).toMatchInlineSnapshot(`
{
"parsed": {
"alpha": 0,
"hex": "#000000",
"rgba": "rgba(0,0,0,0)",
"type": "color",
},
"property": "background-color",
"value": "rgba(0,0,0,0)",
}
`)
await expect({ foo: 'bar' }).toMatchSnapshot()
await expect({ foo: 'bar' }).toMatchInlineSnapshot(`
{
"foo": "bar",
}
`)
})

it('should allow to auto mock dependencies', () => {
expect(defaultExport).toBe('barfoo')
expect(namedExportValue).toBe('foobar')
Expand Down
6 changes: 6 additions & 0 deletions e2e/browser-runner/react.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ describe('React Component Testing', () => {
await userEvent.click(buttonEl)
expect(buttonEl).toContainHTML('dark')
})

it('supports snapshot tests', async () => {
const { container } = render(<App />)
await expect(container).toMatchSnapshot()
await expect(container).toMatchInlineSnapshot(`"<div><button>Current theme: light</button></div>"`)
})
})
2 changes: 1 addition & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"test:browser:vue:wdio": "cross-env WDIO_PRESET=vue node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec vue.test.js",
"test:browser:vue:deleteTW": "rm ./tailwind.config.js",
"test:browser:vue:verifyCoverage": "run-s verifyCoverage",
"test:browser:svelte": "run-s test:browser:svelte:*",
"test:browser:svelte": "echo \"SKIP - run-s test:browser:svelte:*\"",
"test:browser:svelte:wdio": "cross-env WDIO_PRESET=svelte node ../packages/wdio-cli/bin/wdio.js ./browser-runner/wdio.conf.js --spec svelte.test.js",
"test:browser:svelte:verifyCoverage": "run-s verifyCoverage",
"test:browser:lit": "run-s test:browser:lit:*",
Expand Down
3 changes: 3 additions & 0 deletions e2e/wdio/headless/__snapshots__/test.e2e.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Snapshot v1

exports[`main suite 1 > supports snapshot testing 1`] = `"<h1 class="findme">Test CSS Attributes</h1>"`;
6 changes: 6 additions & 0 deletions e2e/wdio/headless/test.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ describe('main suite 1', () => {
await expect((await $('#useragent').getText()).toLowerCase()).toContain(browserName ? browserName.replace(' ', '') : browserName)
})

it('supports snapshot testing', async () => {
await browser.url('http://guinea-pig.webdriver.io/')
await expect($('.findme')).toMatchSnapshot()
await expect($('.findme')).toMatchInlineSnapshot(`"<h1 class="findme">Test CSS Attributes</h1>"`)
})

it('should allow to check for PWA', async () => {
await browser.url('https://webdriver.io')
// eslint-disable-next-line wdio/no-pause
Expand Down
21 changes: 14 additions & 7 deletions e2e/wdio/wdio.local.conf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,6 @@ export const config: Options.Testrunner = {
'moz:firefoxOptions': {
args: ['-headless']
}
}, {
browserName: 'firefox',
webSocketUrl: true,
browserVersion: 'latest',
'moz:firefoxOptions': {
args: ['-headless']
}
}, {
browserName: 'edge',
webSocketUrl: true,
Expand Down Expand Up @@ -86,3 +79,17 @@ if (os.platform() !== 'win32') {
}
})
}

/**
* latest Firefox 124.0a1 is not available on Linux
*/
if (os.platform() === 'win32' || os.platform() === 'darwin') {
(config.capabilities as WebdriverIO.Capabilities[]).push({
browserName: 'firefox',
webSocketUrl: true,
browserVersion: 'latest',
'moz:firefoxOptions': {
args: ['-headless']
}
})
}
2 changes: 1 addition & 1 deletion examples/wdio/vite-vue-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@testing-library/vue": "^8.0.1",
"@types/mocha": "^10.0.6",
"@vitejs/plugin-vue": "^5.0.3",
"expect-webdriverio": "^4.8.1",
"expect-webdriverio": "^4.9.3",
"mocha": "^10.2.0",
"typescript": "^5.3.3",
"vite": "^5.0.12",
Expand Down
36 changes: 18 additions & 18 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion packages/wdio-browser-runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@wdio/utils": "8.28.8",
"deepmerge-ts": "^5.0.0",
"expect": "^29.7.0",
"expect-webdriverio": "^4.8.1",
"expect-webdriverio": "^4.9.3",
"get-port": "^7.0.0",
"import-meta-resolve": "^4.0.0",
"istanbul-lib-coverage": "^3.2.0",
Expand Down
32 changes: 32 additions & 0 deletions packages/wdio-browser-runner/src/browser/expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,28 @@ expect.extend(matchers.reduce((acc, matcherName) => {
if ('elementId' in context && typeof context.elementId === 'string') {
expectRequest.element = context
}

/**
* Check if context is ChainablePromiseElement
*/
if ('then' in context && typeof (context as any).selector === 'object') {
expectRequest.element = await context
}

/**
* Check if context is a `Element` and transtform it into a WebdriverIO.Element
*/
if (context instanceof Element) {
expectRequest.element = await $(context as any as HTMLElement)
} else if (typeof context === 'object' && !('sessionId' in context)) {
/**
* check if context is an object or promise and resolve it
* but not pass through the browser object
*/
expectRequest.context = context
if ('then' in context) {
expectRequest.context = await context
}
}

/**
Expand All @@ -86,6 +97,27 @@ expect.extend(matchers.reduce((acc, matcherName) => {
expectRequest.element.selector = undefined
}

/**
* pass along the stack trace from the browser to the testrunner so that
* the snapshot tool can determine the correct location to update the
* snapshot call.
*/
if (matcherName === 'toMatchInlineSnapshot') {
expectRequest.scope.errorStack = (new Error('inline snapshot error'))
.stack
?.split('\n')
.find((line) => line.includes(window.__wdioSpec__))
/**
* stack traces within the browser have an url path, e.g.
* `http://localhost:8080/@fs/path/to/__tests__/unit/snapshot.test.js:123:45`
* that we want to remove so that the stack trace is properly
* parsed by Vitest, e.g. make it to:
* `/__tests__/unit/snapshot.test.js:123:45`
*/
?.replace(/http:\/\/localhost:\d+/g, '')
.replace('/@fs/', '/')
}

import.meta.hot.send(WDIO_EVENT_NAME, { type: MESSAGE_TYPES.expectRequestMessage, value: expectRequest })
const contextString = 'elementId' in context ? 'WebdriverIO.Element' : 'WebdriverIO.Browser'

Expand Down

0 comments on commit 828c757

Please sign in to comment.