Skip to content

Commit

Permalink
fix: enable WINDOW_DPI to control final sizes during tests (#72)
Browse files Browse the repository at this point in the history
This release enables environment variables changes during tests, that can be useful on many ways.

Also, kudos to Tomohiro for making the whole tests more cross-platform, thank you!

Some refactoring was made to keep the codebase clean as possible.

Co-authored-by: Alvaro Cabrera Durán <[email protected]>
Co-authored-by: NAKAMURA, Tomohiro <[email protected]>
  • Loading branch information
pateketrueke and tomoh1r authored Aug 31, 2024
1 parent 9ffa1a4 commit 7dc3b9d
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 44 deletions.
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"node": true,
"browser": true
},
"globals": {
"fixture": "readonly",
"test": "readonly"
},
"extends": "airbnb-base",
"parserOptions": {
"sourceType": "module"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: tacoss/nodejs@master
- name: Run tests
uses: DevExpress/testcafe-action@latest
with:
args: make ci
args: "chrome --screenshots-full-page -s e2e/screens --color -a 'npm run serve' e2e/cases"
env:
BASE_URL: http://localhost:3000
WINDOW_DPI: 1
56 changes: 56 additions & 0 deletions e2e/cases/cli.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { existsSync } from 'node:fs';
import { join } from 'node:path';

import sizeOf from 'image-size';
import { rimrafSync } from 'rimraf';

import {
getBaseUrl, fixedSize, fixedFile, callTC,
} from '../lib';

fixture('Testing cli --take-snapshot').page(getBaseUrl());

test('should care arg without name', async t => {
const basePath = join('e2e', 'screens', 'Testing_cli', 'assert__it');
rimrafSync(basePath);

await callTC('e2e/file/cases/takesnapshot.test.js', ['--take-snapshot', 'base', '-t', 'takesnapshot']);

await t.expect(existsSync(join(basePath, fixedFile('base.png')))).ok();
});

test('should care arg with name', async t => {
const basePath = join('e2e', 'screens', 'Testing_cli', 'assert__it');
rimrafSync(basePath);

const fpath = 'e2e/file/cases/takesnapshot.test.js';
await callTC(fpath, ['--take-snapshot', 'base', '-t', 'takesnapshot']);
await callTC(fpath, ['--take-snapshot', 'actual', '-t', 'takesnapshot']);
await callTC(fpath, ['--take-snapshot', 'foo', '-t', 'takesnapshot']);

await t.expect(existsSync(join(basePath, fixedFile('base.png')))).ok();
await t.expect(existsSync(join(basePath, fixedFile('actual.png')))).ok();
await t.expect(existsSync(join(basePath, fixedFile('foo.png')))).ok();
await t.expect(existsSync(join(basePath, fixedFile('bar.png')))).notOk();
});

fixture('Testing cli --full-page').page(getBaseUrl());

test('should care arg', async t => {
const basePath = join('e2e', 'screens', 'Testing_cli');
rimrafSync(basePath);

const fpath = 'e2e/file/cases/takesnapshot.test.js';
await callTC(fpath, ['--take-snapshot', '--full-page', '-t', 'fullpage']);
await callTC(fpath, ['--take-snapshot', '-t', 'nofullpage']);

const pngFull = sizeOf(join(basePath, 'assert__it__with__fullpage', fixedFile('base.png')));
await t.expect(pngFull.width).eql(fixedSize(1290));
await t.expect(pngFull.height).gte(fixedSize(1356));

const pngNoFull = sizeOf(join(basePath, 'assert__it__without__fullpage', fixedFile('base.png')));
await t.expect(pngNoFull.width).gte(fixedSize(623));
await t.expect(pngNoFull.width).lte(fixedSize(640));
await t.expect(pngNoFull.height).gte(fixedSize(463));
await t.expect(pngNoFull.height).lte(fixedSize(480));
});
26 changes: 14 additions & 12 deletions e2e/cases/main.test.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,46 @@
import { Selector } from 'testcafe';

import { getBaseUrl } from '../lib';
import { takeSnapshot } from '../../lib';

fixture('Testing')
.page(`${process.env.BASE_URL}/`);
fixture('Testing').page(getBaseUrl());

test('should render "It works!"', async t => {
process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';

await t.wait(1000);
await takeSnapshot(t, 'before_assert_it_works');

await t
.expect(Selector('h1').exists).ok()
.expect(Selector('h1').visible).ok()
.expect(Selector('h1').innerText).contains('It works!');
.expect(Selector('h1').innerText)
.contains('It works!');

await takeSnapshot(t, 'after_assert_it_works');
});

fixture('Testing fullPage')
.page(`${process.env.BASE_URL}/`);
fixture('Testing fullPage').page(getBaseUrl());

test('should render "It works!"', async t => {
process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';

await t.wait(1000);
await takeSnapshot(t, { label: 'before_assert_fullpage', fullPage: true });

await t
.expect(Selector('h1').exists).ok()
.expect(Selector('h1').visible).ok()
.expect(Selector('h1').innerText).contains('It works!');
.expect(Selector('h1').innerText)
.contains('It works!');

await takeSnapshot(t, { label: 'after_assert_fullpage', fullPage: true });
});

fixture('Testing blockOut')
.page(`${process.env.BASE_URL}/`);
fixture('Testing blockOut').page(getBaseUrl());

test('should render "It works!"', async t => {
process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';

await t.wait(1000);

Expand All @@ -52,7 +53,8 @@ test('should render "It works!"', async t => {
await t
.expect(Selector('h1').exists).ok()
.expect(Selector('h1').visible).ok()
.expect(Selector('h1').innerText).contains('It works!');
.expect(Selector('h1').innerText)
.contains('It works!');

await takeSnapshot(t, { label: 'after_assert_blockout', blockOut: elements, fullPage: true });
});
53 changes: 26 additions & 27 deletions e2e/cases/setting.test.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,76 @@
import { existsSync } from 'node:fs';
const { join } = require('node:path');
import { join } from 'node:path';

import sizeOf from 'image-size';
import { rimrafSync } from 'rimraf';

import { getBaseUrl, fixedSize, fixedFile } from '../lib';
import { takeSnapshot } from '../../lib';

fixture('Testing set FULL_PAGE')
.page(`${process.env.BASE_URL}/`);
fixture('Testing set FULL_PAGE').page(getBaseUrl());

test('should care environment variables', async t => {
process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';

const basePath = join('e2e', 'screens', 'Testing_set_FULL__PAGE');
rimrafSync(basePath);

process.env.FULL_PAGE = "1";
process.env.FULL_PAGE = '1';
await t.resizeWindow(640, 480);
await takeSnapshot(t, 'after_set_env');

delete process.env.FULL_PAGE;
await takeSnapshot(t, 'after_del_env');

const pngWithEnv = sizeOf(join(basePath, 'after__set__env', 'base.png'));
await t.expect(pngWithEnv.width).eql(1290);
await t.expect(pngWithEnv.height).eql(1367);
const pngWithEnv = sizeOf(join(basePath, 'after__set__env', fixedFile('base.png')));
await t.expect(pngWithEnv.width).eql(fixedSize(1290));
await t.expect(pngWithEnv.height).gte(fixedSize(1356));

const pngWithOutEnv = sizeOf(join(basePath, 'after__del__env', 'base.png'));
await t.expect(pngWithOutEnv.width).eql(625);
await t.expect(pngWithOutEnv.height).eql(465);
const pngWithOutEnv = sizeOf(join(basePath, 'after__del__env', fixedFile('base.png')));
await t.expect(pngWithOutEnv.width).gte(fixedSize(623));
await t.expect(pngWithOutEnv.width).lte(fixedSize(640));
await t.expect(pngWithOutEnv.height).gte(fixedSize(463));
await t.expect(pngWithOutEnv.height).lte(fixedSize(480));
});

fixture('Testing set TAKE_SNAPSHOT')
.page(`${process.env.BASE_URL}/`);
fixture('Testing set TAKE_SNAPSHOT').page(getBaseUrl());

test('should care environment variables', async t => {
const basePath = join('e2e', 'screens', 'Testing_set_TAKE__SNAPSHOT');
rimrafSync(basePath);

await t.wait(1000);

process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';
await takeSnapshot(t, 'after_set_env');

delete process.env.TAKE_SNAPSHOT
delete process.env.TAKE_SNAPSHOT;
await takeSnapshot(t, 'after_del_env');

await t.expect(existsSync(join(basePath, 'after__set__env', 'base.png'))).ok();
await t.expect(existsSync(join(basePath, 'after__del__env', 'base.png'))).notOk();
await t.expect(existsSync(join(basePath, 'after__set__env', fixedFile('base.png')))).ok();
await t.expect(existsSync(join(basePath, 'after__del__env', fixedFile('base.png')))).notOk();
});

fixture('Testing set SNAPSHOT_NAME')
.page(`${process.env.BASE_URL}/`);
fixture('Testing set SNAPSHOT_NAME').page(getBaseUrl());

test('should care environment variables', async t => {
process.env.TAKE_SNAPSHOT = "1";
process.env.TAKE_SNAPSHOT = '1';

const basePath = join('e2e', 'screens', 'Testing_set_SNAPSHOT__NAME');
rimrafSync(basePath);

await t.wait(1000);

process.env.SNAPSHOT_NAME = "base";
process.env.SNAPSHOT_NAME = 'base';
await takeSnapshot(t, 'after_set_env_base');

process.env.SNAPSHOT_NAME = "actual";
process.env.SNAPSHOT_NAME = 'actual';
await takeSnapshot(t, 'after_set_env_actual');

process.env.SNAPSHOT_NAME = "foo";
process.env.SNAPSHOT_NAME = 'foo';
await takeSnapshot(t, 'after_set_env_foo');


await t.expect(existsSync(join(basePath, 'after__set__env__base', 'base.png'))).ok();
await t.expect(existsSync(join(basePath, 'after__set__env__actual', 'actual.png'))).ok();
await t.expect(existsSync(join(basePath, 'after__set__env__foo', 'foo.png'))).ok();
await t.expect(existsSync(join(basePath, 'after__set__env__base', fixedFile('base.png')))).ok();
await t.expect(existsSync(join(basePath, 'after__set__env__actual', fixedFile('actual.png')))).ok();
await t.expect(existsSync(join(basePath, 'after__set__env__foo', fixedFile('foo.png')))).ok();
});
18 changes: 18 additions & 0 deletions e2e/file/cases/takesnapshot.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getBaseUrl } from '../../lib';
import { takeSnapshot } from '../../../lib';

fixture('Testing cli').page(getBaseUrl());

test('takesnapshot', async t => {
await takeSnapshot(t, 'assert_it');
});

test('fullpage', async t => {
await t.resizeWindow(640, 480);
await takeSnapshot(t, 'assert_it_with_fullpage');
});

test('nofullpage', async t => {
await t.resizeWindow(640, 480);
await takeSnapshot(t, 'assert_it_without_fullpage');
});
43 changes: 43 additions & 0 deletions e2e/lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { spawn } from 'node:child_process';
import process from 'node:process';

// this enforces a particular DPI to allow
// tests to behave in a deterministic way!!
process.env.WINDOW_DPI = process.env.WINDOW_DPI || '2';

function getBaseUrl() {
return `${process.env.BASE_URL}/`;
}

function fixedSize(value) {
return value * process.env.WINDOW_DPI;
}

function fixedFile(name) {
if (process.env.WINDOW_DPI > 1) {
return name.replace('.', `@${process.env.WINDOW_DPI}.`);
}
return name;
}

function callNpx(args) {
const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx';

return new Promise(function fn(resolve) {
const cmd = spawn(npx, args, { shell: true, stdio: 'inherit' });

cmd.on('close', function onClose() {
resolve();
});
});
}

function callTC(targetTest, additionalArgs) {
const browser = process.env.BROWSER != null ? process.env.BROWSER : 'chrome:headless';
const baseArgs = ['testcafe', browser, targetTest, '-s', 'path=e2e/screens', '-q'];
return callNpx(baseArgs.concat(additionalArgs));
}

export {
getBaseUrl, fixedSize, fixedFile, callTC,
};
4 changes: 3 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ function _takeSnapshot(t, opts, extra) {
debug(`Selector('${x[key].fn}') was not found on the DOM`, options);
}

const getWindowDPI = ClientFunction(() => window.devicePixelRatio).with({ boundTestRun: t });
const getWindowDPI = process.env.WINDOW_DPI
? (() => Promise.resolve(+process.env.WINDOW_DPI))
: ClientFunction(() => window.devicePixelRatio).with({ boundTestRun: t });

let dpi;
function fixedName() {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
"build": "bili --format umd-min --module-name reporter --minimal --file-name reporter.umd.js",
"serve": "sirv e2e/public --port 3000",
"prepublish": "npm run dist",
"pretest": "eslint src lib",
"pretest": "eslint src lib e2e",
"test": "npm run test:e2e -- -a 'npm run serve' e2e/cases",
"test:e2e": "BASE_URL=http://localhost:3000 testcafe ${BROWSER:-chrome:headless} --screenshots-full-page -s e2e/screens"
"test:e2e": "BASE_URL=http://localhost:3000 testcafe ${BROWSER:-chrome:headless} --screenshots-full-page -s e2e/screens -q"
},
"author": "Alvaro Cabrera <[email protected]>",
"license": "MIT",
Expand Down

0 comments on commit 7dc3b9d

Please sign in to comment.