creevey 0.10.0-beta.8 → 0.10.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORS +2 -0
- package/CHANGELOG.md +281 -0
- package/README.md +19 -41
- package/dist/client/addon/components/Addon.js +18 -8
- package/dist/client/addon/components/Addon.js.map +1 -1
- package/dist/client/addon/components/Panel.js +4 -4
- package/dist/client/addon/components/Panel.js.map +1 -1
- package/dist/client/addon/components/TestSelect.js +2 -2
- package/dist/client/addon/components/TestSelect.js.map +1 -1
- package/dist/client/addon/components/Tools.js +19 -9
- package/dist/client/addon/components/Tools.js.map +1 -1
- package/dist/client/addon/controller.d.ts +1 -1
- package/dist/client/addon/controller.js +3 -3
- package/dist/client/addon/controller.js.map +1 -1
- package/dist/client/addon/decorator.d.ts +1 -1
- package/dist/client/addon/makeDecorator.d.ts +9 -0
- package/dist/client/addon/makeDecorator.js +48 -0
- package/dist/client/addon/makeDecorator.js.map +1 -0
- package/dist/client/addon/manager.js +38 -39
- package/dist/client/addon/manager.js.map +1 -1
- package/dist/client/addon/preset.d.ts +0 -1
- package/dist/client/addon/preset.js +3 -2
- package/dist/client/addon/preset.js.map +1 -1
- package/dist/client/addon/preview.d.ts +1 -1
- package/dist/client/addon/withCreevey.d.ts +5 -3
- package/dist/client/addon/withCreevey.js +14 -21
- package/dist/client/addon/withCreevey.js.map +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/BlendView.js +18 -8
- package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/ImagesView.js +1 -1
- package/dist/client/shared/components/ImagesView/ImagesView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SideBySideView.js +19 -9
- package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SlideView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SlideView.js +19 -9
- package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SwapView.d.ts +2 -2
- package/dist/client/shared/components/ImagesView/SwapView.js +31 -9
- package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/common.d.ts +1 -1
- package/dist/client/shared/components/PageFooter/PageFooter.js +1 -1
- package/dist/client/shared/components/PageFooter/PageFooter.js.map +1 -1
- package/dist/client/shared/components/PageFooter/Paging.js +1 -1
- package/dist/client/shared/components/PageFooter/Paging.js.map +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.d.ts +2 -2
- package/dist/client/shared/components/PageHeader/ImagePreview.js +2 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
- package/dist/client/shared/components/PageHeader/PageHeader.js +34 -13
- package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/client/shared/components/ResultsPage.d.ts +2 -2
- package/dist/client/shared/components/ResultsPage.js +45 -15
- package/dist/client/shared/components/ResultsPage.js.map +1 -1
- package/dist/client/shared/creeveyClientApi.js +18 -1
- package/dist/client/shared/creeveyClientApi.js.map +1 -1
- package/dist/client/shared/helpers.d.ts +1 -3
- package/dist/client/shared/helpers.js +4 -19
- package/dist/client/shared/helpers.js.map +1 -1
- package/dist/client/web/CreeveyApp.d.ts +1 -0
- package/dist/client/web/CreeveyApp.js +44 -15
- package/dist/client/web/CreeveyApp.js.map +1 -1
- package/dist/client/web/CreeveyContext.d.ts +6 -0
- package/dist/client/web/CreeveyContext.js +21 -7
- package/dist/client/web/CreeveyContext.js.map +1 -1
- package/dist/client/web/CreeveyLoader.d.ts +1 -1
- package/dist/client/web/CreeveyLoader.js +3 -3
- package/dist/client/web/CreeveyLoader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Checkbox.d.ts +4 -4
- package/dist/client/web/CreeveyView/SideBar/Checkbox.js +36 -6
- package/dist/client/web/CreeveyView/SideBar/Checkbox.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Search.js +20 -10
- package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBar.js +26 -12
- package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +67 -13
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +32 -12
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +20 -13
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestLink.js +20 -13
- package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +2 -2
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.js +3 -2
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Toggle.js +1 -1
- package/dist/client/web/CreeveyView/SideBar/Toggle.js.map +1 -1
- package/dist/client/web/KeyboardEventsContext.d.ts +1 -8
- package/dist/client/web/KeyboardEventsContext.js +79 -64
- package/dist/client/web/KeyboardEventsContext.js.map +1 -1
- package/dist/client/web/assets/index-CtSq3IhG.js +518 -0
- package/dist/client/web/index.html +1 -1
- package/dist/client/web/index.js +26 -11
- package/dist/client/web/index.js.map +1 -1
- package/dist/client/web/themes.d.ts +2 -0
- package/dist/client/web/themes.js +22 -0
- package/dist/client/web/themes.js.map +1 -0
- package/dist/creevey.d.ts +1 -1
- package/dist/creevey.js +122 -41
- package/dist/creevey.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/playwright/generator.d.ts +25 -0
- package/dist/playwright/generator.js +243 -0
- package/dist/playwright/generator.js.map +1 -0
- package/dist/playwright/helpers.d.ts +2 -0
- package/dist/playwright/helpers.js +29 -0
- package/dist/playwright/helpers.js.map +1 -0
- package/dist/playwright/reporter.d.ts +83 -0
- package/dist/playwright/reporter.js +334 -0
- package/dist/playwright/reporter.js.map +1 -0
- package/dist/playwright/setup.d.ts +3 -0
- package/dist/playwright/setup.js +72 -0
- package/dist/playwright/setup.js.map +1 -0
- package/dist/playwright.d.ts +1 -0
- package/dist/playwright.js +3 -1
- package/dist/playwright.js.map +1 -1
- package/dist/server/compare.d.ts +18 -0
- package/dist/server/compare.js +182 -0
- package/dist/server/compare.js.map +1 -0
- package/dist/server/config.d.ts +3 -3
- package/dist/server/config.js +75 -8
- package/dist/server/config.js.map +1 -1
- package/dist/server/connection.d.ts +3 -0
- package/dist/server/connection.js +28 -0
- package/dist/server/connection.js.map +1 -0
- package/dist/server/docker.d.ts +1 -1
- package/dist/server/docker.js +54 -32
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +165 -64
- package/dist/server/index.js.map +1 -1
- package/dist/server/master/api.d.ts +11 -6
- package/dist/server/master/api.js +88 -25
- package/dist/server/master/api.js.map +1 -1
- package/dist/server/master/handlers/capture-handler.d.ts +5 -0
- package/dist/server/master/handlers/capture-handler.js +25 -0
- package/dist/server/master/handlers/capture-handler.js.map +1 -0
- package/dist/server/master/handlers/index.d.ts +4 -0
- package/dist/server/master/handlers/index.js +21 -0
- package/dist/server/master/handlers/index.js.map +1 -0
- package/dist/server/master/handlers/ping-handler.d.ts +2 -0
- package/dist/server/master/handlers/ping-handler.js +8 -0
- package/dist/server/master/handlers/ping-handler.js.map +1 -0
- package/dist/server/master/handlers/static-handler.d.ts +1 -0
- package/dist/server/master/handlers/static-handler.js +20 -0
- package/dist/server/master/handlers/static-handler.js.map +1 -0
- package/dist/server/master/handlers/stories-handler.d.ts +4 -0
- package/dist/server/master/handlers/stories-handler.js +24 -0
- package/dist/server/master/handlers/stories-handler.js.map +1 -0
- package/dist/server/master/master.js +7 -24
- package/dist/server/master/master.js.map +1 -1
- package/dist/server/master/pool.d.ts +1 -0
- package/dist/server/master/pool.js +5 -3
- package/dist/server/master/pool.js.map +1 -1
- package/dist/server/master/queue.d.ts +1 -1
- package/dist/server/master/queue.js +14 -6
- package/dist/server/master/queue.js.map +1 -1
- package/dist/server/master/runner.d.ts +6 -6
- package/dist/server/master/runner.js +98 -130
- package/dist/server/master/runner.js.map +1 -1
- package/dist/server/master/server.d.ts +1 -1
- package/dist/server/master/server.js +193 -88
- package/dist/server/master/server.js.map +1 -1
- package/dist/server/master/start.d.ts +1 -2
- package/dist/server/master/start.js +13 -29
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/master/testsManager.d.ts +81 -0
- package/dist/server/master/testsManager.js +282 -0
- package/dist/server/master/testsManager.js.map +1 -0
- package/dist/server/playwright/docker-file.d.ts +1 -1
- package/dist/server/playwright/docker-file.js +17 -8
- package/dist/server/playwright/docker-file.js.map +1 -1
- package/dist/server/playwright/docker.d.ts +2 -1
- package/dist/server/playwright/docker.js +10 -2
- package/dist/server/playwright/docker.js.map +1 -1
- package/dist/server/playwright/index-source.mjs +16 -0
- package/dist/server/playwright/internal.d.ts +7 -7
- package/dist/server/playwright/internal.js +144 -84
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.d.ts +3 -3
- package/dist/server/playwright/webdriver.js +0 -6
- package/dist/server/playwright/webdriver.js.map +1 -1
- package/dist/server/providers/browser.js +4 -3
- package/dist/server/providers/browser.js.map +1 -1
- package/dist/server/providers/hybrid.js +2 -2
- package/dist/server/providers/hybrid.js.map +1 -1
- package/dist/server/report.d.ts +10 -0
- package/dist/server/report.js +45 -0
- package/dist/server/report.js.map +1 -0
- package/dist/server/reporters/creevey.d.ts +7 -0
- package/dist/server/reporters/creevey.js +63 -0
- package/dist/server/reporters/creevey.js.map +1 -0
- package/dist/server/reporters/index.d.ts +2 -0
- package/dist/server/reporters/index.js +16 -0
- package/dist/server/reporters/index.js.map +1 -0
- package/dist/server/reporters/junit.d.ts +16 -0
- package/dist/server/reporters/junit.js +167 -0
- package/dist/server/reporters/junit.js.map +1 -0
- package/dist/server/reporters/teamcity.d.ts +7 -0
- package/dist/server/reporters/teamcity.js +60 -0
- package/dist/server/reporters/teamcity.js.map +1 -0
- package/dist/server/selenium/internal.d.ts +4 -4
- package/dist/server/selenium/internal.js +56 -40
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/selenoid.js +12 -6
- package/dist/server/selenium/selenoid.js.map +1 -1
- package/dist/server/selenium/webdriver.d.ts +3 -3
- package/dist/server/selenium/webdriver.js +4 -8
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/shutdown.d.ts +1 -0
- package/dist/server/shutdown.js +23 -0
- package/dist/server/shutdown.js.map +1 -0
- package/dist/server/stories.d.ts +0 -1
- package/dist/server/stories.js +0 -12
- package/dist/server/stories.js.map +1 -1
- package/dist/server/telemetry.js +3 -3
- package/dist/server/telemetry.js.map +1 -1
- package/dist/server/testsFiles/parser.js +45 -5
- package/dist/server/testsFiles/parser.js.map +1 -1
- package/dist/server/utils.d.ts +23 -0
- package/dist/server/utils.js +114 -15
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +1 -1
- package/dist/server/worker/context.d.ts +3 -0
- package/dist/server/worker/context.js +15 -0
- package/dist/server/worker/context.js.map +1 -0
- package/dist/server/worker/match-image.d.ts +8 -12
- package/dist/server/worker/match-image.js +11 -178
- package/dist/server/worker/match-image.js.map +1 -1
- package/dist/server/worker/start.d.ts +2 -2
- package/dist/server/worker/start.js +41 -64
- package/dist/server/worker/start.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +9 -7
- package/dist/shared/index.js.map +1 -1
- package/dist/types.d.ts +84 -43
- package/dist/types.js +65 -1
- package/dist/types.js.map +1 -1
- package/docs/cli.md +80 -0
- package/docs/config.md +179 -165
- package/docs/examples/playwright-reporer/playwright.config.ts +37 -0
- package/docs/migration-0.9-to-0.10.md +144 -0
- package/docs/playwright-reporter.md +357 -0
- package/docs/storybook.md +60 -0
- package/docs/tests.md +50 -45
- package/package.json +78 -83
- package/playwright.config.mts +46 -0
- package/src/client/addon/components/Addon.tsx +1 -1
- package/src/client/addon/components/Panel.tsx +4 -4
- package/src/client/addon/components/TestSelect.tsx +2 -2
- package/src/client/addon/components/Tools.tsx +2 -2
- package/src/client/addon/controller.ts +4 -4
- package/src/client/addon/makeDecorator.ts +69 -0
- package/src/client/addon/manager.ts +38 -37
- package/src/client/addon/preset.ts +2 -1
- package/src/client/addon/withCreevey.ts +16 -19
- package/src/client/shared/components/ImagesView/BlendView.tsx +1 -1
- package/src/client/shared/components/ImagesView/ImagesView.tsx +1 -1
- package/src/client/shared/components/ImagesView/SideBySideView.tsx +2 -2
- package/src/client/shared/components/ImagesView/SlideView.tsx +2 -2
- package/src/client/shared/components/ImagesView/SwapView.tsx +20 -2
- package/src/client/shared/components/ImagesView/common.ts +1 -1
- package/src/client/shared/components/PageFooter/PageFooter.tsx +1 -1
- package/src/client/shared/components/PageFooter/Paging.tsx +1 -1
- package/src/client/shared/components/PageHeader/ImagePreview.tsx +2 -1
- package/src/client/shared/components/PageHeader/PageHeader.tsx +23 -7
- package/src/client/shared/components/ResultsPage.tsx +33 -10
- package/src/client/shared/creeveyClientApi.ts +19 -1
- package/src/client/shared/helpers.ts +4 -24
- package/src/client/web/CreeveyApp.tsx +30 -9
- package/src/client/web/CreeveyContext.tsx +11 -0
- package/src/client/web/CreeveyLoader.tsx +2 -2
- package/src/client/web/CreeveyView/SideBar/Checkbox.tsx +3 -3
- package/src/client/web/CreeveyView/SideBar/Search.tsx +4 -4
- package/src/client/web/CreeveyView/SideBar/SideBar.tsx +11 -6
- package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +48 -15
- package/src/client/web/CreeveyView/SideBar/SideBarHeader.tsx +20 -5
- package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +12 -12
- package/src/client/web/CreeveyView/SideBar/TestLink.tsx +10 -10
- package/src/client/web/CreeveyView/SideBar/TestStatusIcon.tsx +2 -2
- package/src/client/web/CreeveyView/SideBar/TestsStatus.tsx +3 -2
- package/src/client/web/CreeveyView/SideBar/Toggle.tsx +1 -1
- package/src/client/web/KeyboardEventsContext.tsx +61 -73
- package/src/client/web/index.tsx +10 -5
- package/src/client/web/themes.ts +24 -0
- package/src/creevey.ts +92 -38
- package/src/playwright/generator.ts +322 -0
- package/src/playwright/helpers.ts +31 -0
- package/src/playwright/reporter.ts +381 -0
- package/src/playwright/setup.ts +84 -0
- package/src/playwright.ts +1 -0
- package/src/server/compare.ts +260 -0
- package/src/server/config.ts +52 -9
- package/src/server/connection.ts +26 -0
- package/src/server/docker.ts +62 -34
- package/src/server/index.ts +166 -79
- package/src/server/master/api.ts +94 -28
- package/src/server/master/handlers/capture-handler.ts +20 -0
- package/src/server/master/handlers/index.ts +4 -0
- package/src/server/master/handlers/ping-handler.ts +6 -0
- package/src/server/master/handlers/static-handler.ts +16 -0
- package/src/server/master/handlers/stories-handler.ts +20 -0
- package/src/server/master/master.ts +10 -27
- package/src/server/master/pool.ts +7 -3
- package/src/server/master/queue.ts +21 -7
- package/src/server/master/runner.ts +123 -134
- package/src/server/master/server.ts +214 -101
- package/src/server/master/start.ts +19 -41
- package/src/server/master/testsManager.ts +316 -0
- package/src/server/playwright/docker-file.ts +20 -8
- package/src/server/playwright/docker.ts +16 -3
- package/src/server/playwright/index-source.mjs +16 -0
- package/src/server/playwright/internal.ts +176 -103
- package/src/server/playwright/webdriver.ts +4 -10
- package/src/server/providers/browser.ts +4 -3
- package/src/server/providers/hybrid.ts +2 -3
- package/src/server/report.ts +51 -0
- package/src/server/reporters/creevey.ts +71 -0
- package/src/server/reporters/index.ts +11 -0
- package/src/server/reporters/junit.ts +207 -0
- package/src/server/reporters/teamcity.ts +74 -0
- package/src/server/selenium/internal.ts +70 -53
- package/src/server/selenium/selenoid.ts +13 -6
- package/src/server/selenium/webdriver.ts +8 -12
- package/src/server/shutdown.ts +19 -0
- package/src/server/stories.ts +1 -12
- package/src/server/telemetry.ts +3 -3
- package/src/server/testsFiles/parser.ts +52 -4
- package/src/server/utils.ts +124 -16
- package/src/server/webdriver.ts +1 -1
- package/src/server/worker/context.ts +14 -0
- package/src/server/worker/match-image.ts +16 -248
- package/src/server/worker/start.ts +49 -79
- package/src/shared/index.ts +10 -8
- package/src/types.ts +91 -58
- package/types/global.d.ts +1 -0
- package/dist/client/web/assets/index-DB8lHlJw.js +0 -591
- package/dist/server/reporter.d.ts +0 -26
- package/dist/server/reporter.js +0 -108
- package/dist/server/reporter.js.map +0 -1
- package/dist/server/update.d.ts +0 -2
- package/dist/server/update.js +0 -53
- package/dist/server/update.js.map +0 -1
- package/src/server/reporter.ts +0 -139
- package/src/server/update.ts +0 -74
@@ -0,0 +1,357 @@
|
|
1
|
+
# Playwright Reporter for Creevey
|
2
|
+
|
3
|
+
Creevey provides a Playwright-compatible reporter that allows you to use Creevey's image comparison, reporting, and UI features with Playwright tests.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
The reporter is included with the Creevey package. Install Playwright and Creevey in your project:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
npm install --save-dev @playwright/test creevey
|
11
|
+
```
|
12
|
+
|
13
|
+
## Configuration
|
14
|
+
|
15
|
+
Add the Creevey reporter to your Playwright configuration file:
|
16
|
+
|
17
|
+
```typescript
|
18
|
+
// playwright.config.ts
|
19
|
+
import { defineConfig } from '@playwright/test';
|
20
|
+
|
21
|
+
export default defineConfig({
|
22
|
+
reporter: [
|
23
|
+
['list'], // Standard Playwright reporter for console output
|
24
|
+
[
|
25
|
+
'creevey/playwright-reporter',
|
26
|
+
{
|
27
|
+
// Optional configuration options
|
28
|
+
reportDir: './report', // Directory for report output
|
29
|
+
screenDir: './images', // Directory for reference images
|
30
|
+
port: 3000, // Port for Creevey UI server
|
31
|
+
debug: false, // Enable debug logging
|
32
|
+
},
|
33
|
+
],
|
34
|
+
],
|
35
|
+
// Other Playwright configuration...
|
36
|
+
});
|
37
|
+
```
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
### Taking Screenshots for Comparison
|
42
|
+
|
43
|
+
The reporter automatically collects screenshots taken during Playwright tests. You can use Playwright's built-in screenshot capabilities:
|
44
|
+
|
45
|
+
#### Using `page.screenshot()`
|
46
|
+
|
47
|
+
```typescript
|
48
|
+
import { test, expect } from '@playwright/test';
|
49
|
+
|
50
|
+
test('capture screenshot with page.screenshot', async ({ page }) => {
|
51
|
+
await page.goto('https://example.com');
|
52
|
+
|
53
|
+
// Take a screenshot and attach it to the test result
|
54
|
+
const screenshot = await page.screenshot();
|
55
|
+
await test.info().attach('example-screenshot', {
|
56
|
+
body: screenshot,
|
57
|
+
contentType: 'image/png',
|
58
|
+
});
|
59
|
+
});
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Using Playwright's expect().toHaveScreenshot()
|
63
|
+
|
64
|
+
```typescript
|
65
|
+
import { test, expect } from '@playwright/test';
|
66
|
+
|
67
|
+
test('capture screenshot with toHaveScreenshot', async ({ page }) => {
|
68
|
+
await page.goto('https://example.com');
|
69
|
+
|
70
|
+
// This will automatically be picked up by the Creevey reporter
|
71
|
+
await expect(page).toHaveScreenshot('example-screenshot.png');
|
72
|
+
});
|
73
|
+
```
|
74
|
+
|
75
|
+
### Adding Creevey Metadata
|
76
|
+
|
77
|
+
You can add metadata to your tests to better organize them in the Creevey UI:
|
78
|
+
|
79
|
+
```typescript
|
80
|
+
import { test } from '@playwright/test';
|
81
|
+
|
82
|
+
test.describe('Homepage', () => {
|
83
|
+
test('header elements @creevey{"storyPath": ["Website", "HomePage"], "browser": "chromium"}', async ({ page }) => {
|
84
|
+
await page.goto('https://example.com');
|
85
|
+
// Test code...
|
86
|
+
await page.screenshot({ path: 'header.png' });
|
87
|
+
});
|
88
|
+
});
|
89
|
+
```
|
90
|
+
|
91
|
+
The `@creevey` annotation accepts a JSON object with the following properties:
|
92
|
+
|
93
|
+
- `storyPath`: Array of strings defining the hierarchy in the Creevey UI
|
94
|
+
- `browser`: Browser name (chromium, firefox, webkit)
|
95
|
+
- `testName`: Custom test name (defaults to the test title)
|
96
|
+
|
97
|
+
### Viewing Results
|
98
|
+
|
99
|
+
After running your tests, you can view the results in the Creevey UI:
|
100
|
+
|
101
|
+
1. Open your browser and navigate to `http://localhost:3000` (or the port you configured)
|
102
|
+
2. Browse test results, view image comparisons, and approve changes
|
103
|
+
|
104
|
+
Run your tests with Playwright:
|
105
|
+
|
106
|
+
```bash
|
107
|
+
npx playwright test
|
108
|
+
```
|
109
|
+
|
110
|
+
The Creevey server will automatically start during the test run, and you'll see a message with the URL once tests complete.
|
111
|
+
|
112
|
+
### Approving Screenshots
|
113
|
+
|
114
|
+
You can approve screenshots directly from the Creevey UI by:
|
115
|
+
|
116
|
+
1. Selecting the test with the failed comparison
|
117
|
+
2. Reviewing the differences between expected and actual images
|
118
|
+
3. Clicking the "Approve" button to update the reference image
|
119
|
+
|
120
|
+
## Advanced Usage
|
121
|
+
|
122
|
+
### Custom Screenshot Names
|
123
|
+
|
124
|
+
You can customize screenshot names to better organize your visual tests:
|
125
|
+
|
126
|
+
```typescript
|
127
|
+
test('product page layout', async ({ page }) => {
|
128
|
+
await page.goto('https://example.com/products/1');
|
129
|
+
|
130
|
+
// Take multiple screenshots in a single test
|
131
|
+
await test.info().attach('product-header', {
|
132
|
+
body: await page.locator('.product-header').screenshot(),
|
133
|
+
contentType: 'image/png',
|
134
|
+
});
|
135
|
+
|
136
|
+
await test.info().attach('product-details', {
|
137
|
+
body: await page.locator('.product-details').screenshot(),
|
138
|
+
contentType: 'image/png',
|
139
|
+
});
|
140
|
+
});
|
141
|
+
```
|
142
|
+
|
143
|
+
### Multiple Screenshots in One Test
|
144
|
+
|
145
|
+
You can capture multiple screenshots in a single test:
|
146
|
+
|
147
|
+
```typescript
|
148
|
+
test('responsive design checks', async ({ page }) => {
|
149
|
+
await page.goto('https://example.com');
|
150
|
+
|
151
|
+
// Mobile view
|
152
|
+
await page.setViewportSize({ width: 375, height: 667 });
|
153
|
+
await test.info().attach('mobile-view', {
|
154
|
+
body: await page.screenshot(),
|
155
|
+
contentType: 'image/png',
|
156
|
+
});
|
157
|
+
|
158
|
+
// Tablet view
|
159
|
+
await page.setViewportSize({ width: 768, height: 1024 });
|
160
|
+
await test.info().attach('tablet-view', {
|
161
|
+
body: await page.screenshot(),
|
162
|
+
contentType: 'image/png',
|
163
|
+
});
|
164
|
+
|
165
|
+
// Desktop view
|
166
|
+
await page.setViewportSize({ width: 1280, height: 800 });
|
167
|
+
await test.info().attach('desktop-view', {
|
168
|
+
body: await page.screenshot(),
|
169
|
+
contentType: 'image/png',
|
170
|
+
});
|
171
|
+
});
|
172
|
+
```
|
173
|
+
|
174
|
+
### Custom Test Names
|
175
|
+
|
176
|
+
By default, the reporter will use the Playwright test title as the test name. You can customize how tests are named by setting meta data:
|
177
|
+
|
178
|
+
```typescript
|
179
|
+
test('home page visual test', async ({ page }) => {
|
180
|
+
test.info().annotations.push({
|
181
|
+
type: 'creevey',
|
182
|
+
description: JSON.stringify({
|
183
|
+
testName: 'custom-test-name',
|
184
|
+
browser: 'chrome', // Optional, to override browser name
|
185
|
+
}),
|
186
|
+
});
|
187
|
+
|
188
|
+
// Test implementation...
|
189
|
+
});
|
190
|
+
```
|
191
|
+
|
192
|
+
### Integration with Existing Creevey Configuration
|
193
|
+
|
194
|
+
If you're already using Creevey for other tests, you can share configuration:
|
195
|
+
|
196
|
+
```typescript
|
197
|
+
import { defineConfig } from '@playwright/test';
|
198
|
+
import creeveyConfig from './creevey.config.js';
|
199
|
+
|
200
|
+
export default defineConfig({
|
201
|
+
reporter: [
|
202
|
+
['list'],
|
203
|
+
[
|
204
|
+
'creevey/playwright-reporter',
|
205
|
+
{
|
206
|
+
reportDir: creeveyConfig.reportDir,
|
207
|
+
screenDir: creeveyConfig.screenDir,
|
208
|
+
port: 3001, // Use a different port to avoid conflicts
|
209
|
+
},
|
210
|
+
],
|
211
|
+
],
|
212
|
+
});
|
213
|
+
```
|
214
|
+
|
215
|
+
### Test Steps Integration
|
216
|
+
|
217
|
+
The reporter supports Playwright's test steps, capturing screenshots at each step:
|
218
|
+
|
219
|
+
```typescript
|
220
|
+
test('multi-step test', async ({ page }) => {
|
221
|
+
await test.step('Step 1: Navigate to home', async () => {
|
222
|
+
await page.goto('/');
|
223
|
+
// Screenshot captured from this step will be associated with "Step 1"
|
224
|
+
await test.info().attach('step1', {
|
225
|
+
body: await page.screenshot(),
|
226
|
+
contentType: 'image/png',
|
227
|
+
});
|
228
|
+
});
|
229
|
+
|
230
|
+
await test.step('Step 2: Click button', async () => {
|
231
|
+
await page.click('.button');
|
232
|
+
// This screenshot will be associated with "Step 2"
|
233
|
+
await test.info().attach('step2', {
|
234
|
+
body: await page.screenshot(),
|
235
|
+
contentType: 'image/png',
|
236
|
+
});
|
237
|
+
});
|
238
|
+
});
|
239
|
+
```
|
240
|
+
|
241
|
+
### Integration with Existing Creevey Server
|
242
|
+
|
243
|
+
If you're already running a Creevey server, you can configure the reporter to use it:
|
244
|
+
|
245
|
+
```typescript
|
246
|
+
[
|
247
|
+
CreeveyPlaywrightReporter,
|
248
|
+
{
|
249
|
+
useExistingServer: true, // Don't start a new server
|
250
|
+
port: 3000, // Port of the existing server
|
251
|
+
},
|
252
|
+
];
|
253
|
+
```
|
254
|
+
|
255
|
+
### Performance Optimization
|
256
|
+
|
257
|
+
For large test suites with many screenshots, you can enable performance optimizations:
|
258
|
+
|
259
|
+
```typescript
|
260
|
+
[
|
261
|
+
CreeveyPlaywrightReporter,
|
262
|
+
{
|
263
|
+
batchProcessing: true, // Process screenshots in batches
|
264
|
+
maxConcurrency: 4, // Maximum concurrent screenshot processing
|
265
|
+
lazyInit: true, // Initialize components on demand
|
266
|
+
},
|
267
|
+
];
|
268
|
+
```
|
269
|
+
|
270
|
+
## API Reference
|
271
|
+
|
272
|
+
### Reporter Options
|
273
|
+
|
274
|
+
| Option | Type | Default | Description |
|
275
|
+
| ------------------------- | ------- | ------------ | ----------------------------------------------------- |
|
276
|
+
| `reportDir` | string | `'./report'` | Directory where Creevey will store reports |
|
277
|
+
| `screenDir` | string | `'./images'` | Directory where reference images are stored |
|
278
|
+
| `port` | number | `3000` | Port number for the Creevey UI server |
|
279
|
+
| `debug` | boolean | `false` | Enable debug logging |
|
280
|
+
| `uiEnabled` | boolean | `true` | Enable or disable the UI server |
|
281
|
+
| `useExistingServer` | boolean | `false` | Use an existing Creevey server instance |
|
282
|
+
| `batchProcessing` | boolean | `false` | Process screenshots in batches for better performance |
|
283
|
+
| `maxConcurrency` | number | `2` | Maximum concurrent screenshot processing operations |
|
284
|
+
| `lazyInit` | boolean | `false` | Initialize components on demand for faster startup |
|
285
|
+
| `retainOrphanedImages` | boolean | `false` | Keep images not associated with current tests |
|
286
|
+
| `customComparisonOptions` | object | `undefined` | Custom options for image comparison |
|
287
|
+
|
288
|
+
## Troubleshooting
|
289
|
+
|
290
|
+
### Common Issues
|
291
|
+
|
292
|
+
- **Port conflicts**: If the Creevey server fails to start, it might be due to port conflicts. Change the port in the configuration.
|
293
|
+
- **Missing screenshots**: Ensure your tests are attaching screenshots with unique names or using `toHaveScreenshot()`.
|
294
|
+
- **Path issues**: If reference images aren't found, check that the `screenDir` path is correct and accessible.
|
295
|
+
|
296
|
+
If screenshots are not appearing in the Creevey UI:
|
297
|
+
|
298
|
+
1. Ensure your screenshots are being properly attached to test results
|
299
|
+
2. Check that the content type is set to 'image/png' when attaching
|
300
|
+
3. Enable debug mode in the reporter configuration to see detailed logs
|
301
|
+
|
302
|
+
### Server Issues
|
303
|
+
|
304
|
+
If the Creevey server fails to start:
|
305
|
+
|
306
|
+
1. Check if the configured port is already in use
|
307
|
+
2. Ensure the report directory is writable
|
308
|
+
3. Look for error messages in the console output
|
309
|
+
|
310
|
+
### Debug Mode
|
311
|
+
|
312
|
+
Enable debug logging for more detailed information:
|
313
|
+
|
314
|
+
```typescript
|
315
|
+
[
|
316
|
+
CreeveyPlaywrightReporter,
|
317
|
+
{
|
318
|
+
debug: true,
|
319
|
+
// Other options...
|
320
|
+
},
|
321
|
+
];
|
322
|
+
```
|
323
|
+
|
324
|
+
## Error Handling
|
325
|
+
|
326
|
+
The reporter is designed to handle errors gracefully:
|
327
|
+
|
328
|
+
- If the reporter fails to initialize, tests will still run and screenshots will be captured when possible
|
329
|
+
- If the server can't start, the reporter will continue to capture screenshots but the UI won't be available
|
330
|
+
- All errors are logged with appropriate severity levels and won't cause your tests to fail
|
331
|
+
|
332
|
+
### Debugging Reporter Issues
|
333
|
+
|
334
|
+
For detailed debugging information, enable debug mode and check the logs:
|
335
|
+
|
336
|
+
```typescript
|
337
|
+
[
|
338
|
+
CreeveyPlaywrightReporter,
|
339
|
+
{
|
340
|
+
debug: true,
|
341
|
+
},
|
342
|
+
];
|
343
|
+
```
|
344
|
+
|
345
|
+
You can also specify a custom log file for the reporter:
|
346
|
+
|
347
|
+
```typescript
|
348
|
+
[
|
349
|
+
CreeveyPlaywrightReporter,
|
350
|
+
{
|
351
|
+
debug: true,
|
352
|
+
logFile: './creevey-reporter.log',
|
353
|
+
},
|
354
|
+
];
|
355
|
+
```
|
356
|
+
|
357
|
+
For more help, please check the main Creevey documentation or open an issue on GitHub.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
## Creevey Storybook Parameters
|
2
|
+
|
3
|
+
Creevey allows you to customize how stories will be captured. You could define parameters on `global`, `kind` or `story` levels. All these parameters are deeply merged by Storybook for each story.
|
4
|
+
|
5
|
+
```ts
|
6
|
+
// .storybook/preview.tsx
|
7
|
+
export const parameters = {
|
8
|
+
creevey: {
|
9
|
+
// Global parameters are applied to all stories
|
10
|
+
captureElement: '#storybook-root',
|
11
|
+
},
|
12
|
+
};
|
13
|
+
```
|
14
|
+
|
15
|
+
```ts
|
16
|
+
// stories/MyModal.stories.tsx
|
17
|
+
import React from 'react';
|
18
|
+
import { Meta, StoryObj } from '@storybook/react';
|
19
|
+
import { CreeveyMeta, CreeveyStory } from 'creevey';
|
20
|
+
import MyModal from './src/components/MyModal';
|
21
|
+
|
22
|
+
const Kind: Meta<typeof MyModal> = {
|
23
|
+
title: 'MyModal',
|
24
|
+
component: MyModal,
|
25
|
+
parameters: {
|
26
|
+
creevey: {
|
27
|
+
// It's possible to add additional delay before capturing screenshot
|
28
|
+
delay: 1000,
|
29
|
+
|
30
|
+
// For capturing the whole browser viewport, you can define `null` instead of css selector.
|
31
|
+
captureElement: null,
|
32
|
+
|
33
|
+
// You can skip some stories from capturing, by defining `skip` option:
|
34
|
+
// skip: { "The reason why story is skipped": { in: 'chrome', stories: 'Loading' } }
|
35
|
+
// - `in` - browser name, regex or array of browser names, which are defined in the Creevey config
|
36
|
+
// - `stories` - story name, regex or array of story names
|
37
|
+
// - `tests` - test name, regex or array of test names
|
38
|
+
// NOTE: If you try to skip stories by story name, the storybook name format will be used
|
39
|
+
// For more info see [storybook-export-vs-name-handling](https://storybook.js.org/docs/formats/component-story-format/#storybook-export-vs-name-handling))
|
40
|
+
skip: {
|
41
|
+
"`MyModal` doesn't support ie11": { in: 'ie11' },
|
42
|
+
'Loading stories are flaky in firefox': { in: 'firefox', stories: 'Loading' },
|
43
|
+
"`MyModal` hovering doesn't work correctly": {
|
44
|
+
in: ['firefox', 'chrome'],
|
45
|
+
tests: /.*hover$/,
|
46
|
+
},
|
47
|
+
},
|
48
|
+
},
|
49
|
+
},
|
50
|
+
};
|
51
|
+
|
52
|
+
export default Kind;
|
53
|
+
|
54
|
+
export const Basic: StoryObj<typeof MyModal> = {
|
55
|
+
creevey: {
|
56
|
+
// Lastly some elements can be ignored in capturing screenshot
|
57
|
+
ignoreElements: ['button', '.local-time'],
|
58
|
+
},
|
59
|
+
};
|
60
|
+
```
|
package/docs/tests.md
CHANGED
@@ -1,63 +1,68 @@
|
|
1
|
-
## Write tests
|
1
|
+
## Write interactive screenshot tests
|
2
2
|
|
3
|
-
|
3
|
+
In most cases following Storybook's ideology of [writing stories](https://storybook.js.org/docs/get-started/whats-a-story) is enough to test your UI components. Where each component has a separate stories file with its different states. But sometimes you might have pretty complicated components with a lot of interactions and internal states. In this case, you can write tests for your stories.
|
4
4
|
|
5
|
-
|
6
|
-
import React from 'react';
|
7
|
-
import { Story } from '@storybook/react';
|
8
|
-
import { CreeveyStory } from 'creevey';
|
9
|
-
import MyComponent from './src/components/MyComponent';
|
5
|
+
There are two different ways how to write interactive tests with Creevey:
|
10
6
|
|
11
|
-
|
7
|
+
### Write tests in `*.creevey.ts` files
|
12
8
|
|
13
|
-
|
14
|
-
Basic.parameters = {
|
15
|
-
creevey: {
|
16
|
-
captureElement: '#storybook-root',
|
17
|
-
tests: {
|
18
|
-
async click() {
|
19
|
-
await this.browser.actions().click(this.captureElement).perform();
|
9
|
+
It's the recommended way to write tests. It allows you to run these tests by Creevey itself and utilize webdriver benefits. The crucial part of it is webdriver action calls are more close to real user interactions and mitigate flakiness and false-negative results. Here is a simple example of how to write tests in `*.creevey.ts` files
|
20
10
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
11
|
+
```ts
|
12
|
+
// stories/MyComponent.creevey.ts
|
13
|
+
import { kind, story, test } from 'creevey';
|
14
|
+
|
15
|
+
kind('MyComponent', () => {
|
16
|
+
story('Story', ({ setStoryParameters }) => {
|
17
|
+
// It's possible to pass Creevey parameters to story
|
18
|
+
setStoryParameters({
|
19
|
+
captureElement: 'span[data-test-id~="x"]',
|
20
|
+
ignoreElements: [],
|
21
|
+
});
|
22
|
+
|
23
|
+
test('idle', async (context) => {
|
24
|
+
await context.matchImage(await context.takeScreenshot());
|
25
|
+
});
|
26
|
+
|
27
|
+
test('input', async (context) => {
|
28
|
+
await context.webdriver.keyboard.press('Tab');
|
29
|
+
const focus = await context.takeScreenshot();
|
30
|
+
await context.webdriver.keyboard.type('Hello Creevey');
|
31
|
+
const input = await context.takeScreenshot();
|
32
|
+
await context.matchImages({ focus, input });
|
33
|
+
});
|
34
|
+
});
|
35
|
+
});
|
26
36
|
```
|
27
37
|
|
28
|
-
|
38
|
+
In the example above, we used Playwright API to interact with the story. But Creevey also supports Selenium webdriver. And in that case `context.webdriver` will be an instance of Selenium webdriver. Obviously Selenium API is different from Playwright.
|
29
39
|
|
30
|
-
|
40
|
+
### Using Storybook's `play` function
|
31
41
|
|
32
|
-
|
33
|
-
import React from 'react';
|
34
|
-
import { CSFStory } from 'creevey';
|
35
|
-
import MyForm from './src/components/MyForm';
|
42
|
+
Storybook allows you to write tests in the story file itself by using [`play` function](https://storybook.js.org/docs/writing-tests/component-testing). It's a good way to write simple tests. But there are couple drawbacks of this approach:
|
36
43
|
|
37
|
-
|
44
|
+
- You can have only one test per story. Which is not a big deal, but sometimes you might not want to have multiple stories with the same markup.
|
45
|
+
- Tests are running in browser environment and use https://testing-library.com API under the hood. It's good for unit tests, but might not be suitable for visual regression tests, because testing-library relies on DOM API and not even close to real user interactions. For example, you might have a button that could be visible for user, but it's covered by some other transparent element. With testing-library the button easily accessible and clickable, but the user can't interact with it.
|
38
46
|
|
39
|
-
|
40
|
-
Basic.story = {
|
41
|
-
parameters: {
|
42
|
-
creevey: {
|
43
|
-
captureElement: '#storybook-root',
|
44
|
-
delay: 1000,
|
45
|
-
tests: {
|
46
|
-
async submit() {
|
47
|
-
const input = await this.browser.findElement({ css: '.my-input' });
|
47
|
+
Here is an example of how to write tests using Storybook's `play` function:
|
48
48
|
|
49
|
-
|
49
|
+
```tsx
|
50
|
+
// stories/MyComponent.stories.tsx
|
51
|
+
import React from 'react';
|
52
|
+
import { Meta, StoryObj } from '@storybook/react';
|
53
|
+
import { fireEvent, within } from '@storybook/test';
|
54
|
+
import MyComponent from './src/components/MyComponent';
|
50
55
|
|
51
|
-
|
56
|
+
export default {
|
57
|
+
title: 'MyComponent',
|
58
|
+
component: MyComponent,
|
59
|
+
};
|
52
60
|
|
53
|
-
|
61
|
+
export const Basic: StoryObj<typeof MyComponent> = {
|
62
|
+
play: async ({ canvasElement }) => {
|
63
|
+
const slider = await within(canvasElement).findByTestId('slider');
|
54
64
|
|
55
|
-
|
56
|
-
},
|
57
|
-
},
|
58
|
-
},
|
65
|
+
await fireEvent.change(slider, { target: { value: 50 } });
|
59
66
|
},
|
60
67
|
};
|
61
68
|
```
|
62
|
-
|
63
|
-
NOTE: In this example I fill some simple form and submit it. Also as you could see, I taking two different screenshots `empty` and `submitted` and assert these in the end.
|