Skip to content

Commit 700133f

Browse files
committed
test percy
1 parent e16e1dd commit 700133f

File tree

15 files changed

+133
-18
lines changed

15 files changed

+133
-18
lines changed

.percy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
version: 2,
33
percy: {
4-
token: process.env.PERCY_TOKEN,
4+
token: config.get('percy.token'),
55
useSystemProxy: false,
66
skipBaseBuild: false
77
},

config/default.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
import { cucumberTags } from './wdio/cucumber-tags.ts';
1+
import { CUCUMBER_TAGS } from './wdio/cucumber-tags.ts';
22

33
export default {
44
cucumberTags: {
5-
percy: cucumberTags.percy
5+
normal: CUCUMBER_TAGS.normal,
6+
percy: CUCUMBER_TAGS.percy
67
},
8+
percy: {
9+
token: process.env.PERCY_TOKEN
10+
}
711
};

config/wdio/cucumber-tags.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const SEPARATOR = ' and ';
22

3-
export const cucumberTags: Record<'percy' , string> =
3+
export const CUCUMBER_TAGS =
44
{
5-
percy: [' @visual', 'not @fixme', 'not @ignore'].join(SEPARATOR)
5+
normal: ['not @percy', 'not @fixme', 'not @ignore'].join(SEPARATOR),
6+
percy: [' @percy', 'not @fixme', 'not @ignore'].join(SEPARATOR)
67
};

config/wdio/wdio-config-variables.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import config from 'config';
33
type WdioConfigVariables = Record<string, { cucumberOptsTags: string; maxInstances: number }>;
44

55
export const wdioConfigVariables: WdioConfigVariables = {
6+
normal: {
7+
cucumberOptsTags: config.get<string>('cucumberTags.normal'),
8+
maxInstances: 2
9+
},
610
percy: {
711
cucumberOptsTags: config.get<string>('cucumberTags.percy'),
812
maxInstances: 2
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {Before} from '@cucumber/cucumber';
2+
import {engage} from '@serenity-js/core';
3+
4+
import {Actors} from '../../../test/actors';
5+
import {TIME} from '../../../test/constants/datetime.ts';
6+
7+
Before({ timeout: TIME.oneMinuteInMs }, () => engage(new Actors()));
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { Then } from '@cucumber/cucumber';
2-
import percyScreenshot from '@percy/webdriverio';
1+
import {Then} from '@cucumber/cucumber';
2+
import {Actor} from '@serenity-js/core';
33

44
import {LoginForm} from '../../test/authentication/ui/LoginForm.ts';
5+
import {PercySnapshot} from '../../test/interactions/percy-snapshot.ts';
56
import {GetLocator} from '../../test/questions/get-locator.ts';
67

7-
Then('the page should look like the baseline {string}', async (tag: string) =>
8-
await percyScreenshot(tag)
8+
Then('{actor} checks the page should look like the baseline {string}', async (actor: Actor, tag: string) =>
9+
await actor.attemptsTo(PercySnapshot(tag))
910
);
1011

11-
Then('the login form should look like the baseline {string}', async (tag: string) =>
12-
await percyScreenshot(tag, {scope: `${GetLocator(LoginForm.wrapper())}`})
13-
);
12+
Then('{actor} checks the login form should look like the baseline {string}', async (actor: Actor, tag: string) => {
13+
const locator = await actor.answer(GetLocator(LoginForm.loginButton()));
14+
await actor.attemptsTo(PercySnapshot(tag, {scope: locator}))
15+
});
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
Feature: Form-Based Authentication
1+
Feature: Percy Visual Testing
22

33
In order to learn how to implement Percy visual testing
44
As a Curious Developer
55
I'd like to see an example
66

77
Background:
8-
Given Alice starts with the "Percy Visual Testing" example
8+
Given User starts with the "Form Authentication" example
99

1010
@percy
1111
Scenario: Full page should not change
@@ -14,7 +14,7 @@ Feature: Form-Based Authentication
1414
that offers a pixel perfect visual testing service.
1515
Perfect for not missing any unexpected frontend change 😎
1616

17-
Then the page should look like the baseline "the-internet-login-form-full-page"
17+
Then Percy checks the page should look like the baseline "the-internet-login-form-full-page"
1818

1919
@percy
2020
Scenario: Element should not change
@@ -23,4 +23,4 @@ Feature: Form-Based Authentication
2323
existing on a page.
2424
Perfect if you need to reduce the scope in a page 😎
2525

26-
Then the login form should look like the baseline "the-internet-login-form-element"
26+
Then Percy checks the login form should look like the baseline "the-internet-login-form-element"

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"scripts": {
77
"clean": "rimraf target",
88
"test": "failsafe clean test:execute test:report",
9-
"test:execute": "wdio wdio.conf.ts",
9+
"test:visual": "failsafe clean test:percy test:report",
10+
"test:execute": "export EXEC_MODE=normal wdio wdio.conf.ts",
1011
"test:percy": "export EXEC_MODE=percy && percy exec -- wdio wdio.conf.ts",
1112
"test:report": "serenity-bdd run --features ./features",
1213
"start": "mkdirp target/site/serenity && npx http-server -p 8080 target/site/serenity -s -o",

test/abilities/percy-screenshot.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { SnapshotOptions } from '@percy/core';
2+
import percyScreenshot from '@percy/webdriverio';
3+
import { Ability } from '@serenity-js/core';
4+
5+
export class TakePercyScreenshot extends Ability {
6+
constructor() {
7+
super();
8+
}
9+
10+
static using() {
11+
return new TakePercyScreenshot();
12+
}
13+
14+
async with(tag: string, options: SnapshotOptions) {
15+
await percyScreenshot(tag, options);
16+
}
17+
}

test/actors/index.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Actor, Cast } from '@serenity-js/core';
2+
import {BrowseTheWeb} from '@serenity-js/web';
3+
4+
import {TakePercyScreenshot} from '../abilities/percy-screenshot.ts';
5+
import {ACTOR_NAMES} from '../constants/actors.ts';
6+
7+
export class Actors implements Cast {
8+
prepare(actor: Actor): Actor {
9+
switch (actor.name) {
10+
case ACTOR_NAMES.Percy: {
11+
return actor.whoCan(
12+
TakePercyScreenshot.using()
13+
);
14+
}
15+
case ACTOR_NAMES.User: {
16+
return actor.whoCan(
17+
BrowseTheWeb.as(actor)
18+
);
19+
}
20+
default: {
21+
throw new Error(
22+
`There is no actor defined with the given name: ${actor.name}`,
23+
);
24+
}
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)