phantesta v4.0.24
Phantesta
Phantesta is a testing library built on top of selenium. It allows you to write regression tests to ensure a rendered portion of a page does not change.
Requirements
Phantesta depends on ImageMagick.
Please install this before continuing.
Installation
npm install --save-dev phantestaUsage
import { syncify } from 'jasmine_test_utils';
import path from 'path';
import Phantesta from 'phantesta';
describe('my test suite', function() {
var page = null;
var phantesta = null;
var createDriver = async function() {
var tmpdir = fs.mkdtempSync('/tmp/phantesta');
var chromeOpts = new chrome.Options();
chromeOpts.addArguments('--user-data-dir=' + tmpdir);
var profile = new firefox.Profile();
var firefoxOpts = new firefox.Options();
firefoxOpts.setProfile(profile);
return new Builder()
.forBrowser('firefox')
.setChromeOptions(chromeOpts)
.setFirefoxOptions(firefoxOpts)
.build();
};
beforeEach(syncify(async function() {
phantesta = new Phantesta({
screenshotPath: path.resolve(__dirname, '../screenshots'),
});
phantesta.group(__dirname);
page = await createDriver();
}));
afterEach(syncify(async function() {
phantesta.ungroup();
await page.quit();
phantesta.destructiveClearAllSnapshots();
}));
it('should do some tests', syncify(async function() {
await page.open('http://www.google.com');
await phantesta.expect(page).toMatchScreenshot('unique_snapshot_name');
await phantesta.expect(page).toMatchScreenshot('unique_snapshot_name2');
await phantesta.expectSame('unique_snapshot_name', 'unique_snapshot_name2');
await page.open('http://www.asdf.com');
await phantesta.expect(page).toMatchScreenshot('another_website');
await phantesta.expectDiff('unique_snapshot_name', 'another_website');
}));
});Snapshots will be stored in the screenshotPath directory with (default)
suffixes of .good.png, .new.png, .diff.png. You should commit all the
.good.png images to your git repository, and add all the .new.png and
.diff.png images to your .gitignore.
If an image is expected to be stable and it hasn't changed, it will only
have a .good.png in the screenshots directory. If it has changed, there will
be a .new.png and .diff.png, which represent the new screenshot and the
diff between the new screenshot and the old (good) one. If a change is
expected and intentional, overwrite the .good.png image with the .new.png image.
Because the .good.png images are committed to your repository, they will also
show up as changes in your code review tool.
UI for managing screenshots
Eventually, you will have enough snapshots that it becomes a burden to manually inspect and move them around. There is a UI that comes with Phantesta that makes it significantly easier to review and accept changed snapshots. To do so, run
phantesta-server --host localhost --port 7991 --screenshotPath tests/visual/screenshotsthen visit localhost:7991 after running tests. This site will have all the
failed snapshots, with the option to view and accept diffs to snapshots.
Remote Phantesta Server
The remote phantesta server will allow to upload and download snaphots to and from a Remote Server along with the ability to view and review them. To deploy this remote server, simply run
remote-phantesta-server --port 3000 --savePath /tmp/phantestaThe remote server optionally takes in the following arguments:
portdefaults to 3000savePathis the path where screenshots uploaded will be saved in the remote host. Defaults to ~/phantesta
then visit localhost:3000. This site will have a list of phantesta servers created.
Phantesta Servers are created when snapshots are uploaded to the server so that
they can be viewed and reviewed.
To upload snapshots to the server, run
upload-to-remote-phantesta --url localhost:3000 --screenshotPath /home/screenshot --identifier uniqueIdentifierupload-to-remote-phantesta takes in the following arguments:
urlspecifies where the remote server is runningscreenshotPathis the path where all snapshots are located locally. This should be the same as the path which is used when initializing phantestaidentifieris a unique identifier that will be used to set the screenshots and phantesta-servers apart
To download snapshots from the server, run
download-from-remote-phantesta --url localhost:3000 --downloadPath /home/screenshot --identifier identifierUsedWhenUploadingdownload-from-remote-phantesta takes in the following arguments:
urlspecifies where the remote server is runningdownloadPathis the path the where all snapshots would be saved locally when downloadingidentifieris a unique identifier that was used used when uploading screenshots to the remote serverallFiles (optional)if this is set to true, all files including diffs would be downloaded. If set to false (default), it would only let you download files after all diffs have been resolved on the remote server.
API
new Phantesta(options)
optionsis a dict with the keysscreenshotPathdefaults to"tests/visual/screenshots"goodExtdefaults to".good.png"newExtdefaults to".new.png"diffExtdefaults to".diff.png"expectToBedefaults tofunction(actual, expected) { expect(actual).toBe(expected) }expectNotToBedefaults tofunction(actual, expected) { expect(actual).not.toBe(expected) }
Override the expectToBe and expectNotToBe calls with methods from your test framework if you're not using jasmine.
async Phantesta.prototype.expect(page, target) -> ScreenshotExpect
pageis the selenium driver of which a screenshot is to be takentargetis a selector used to target a portion of the page
Passes if the screenshot is unchanged relative to the good name screenshot.
Fails and leaves .new.png and .diff.png images in the screenshotPath if
the screenshot has changed relative to the good name screenshot
async ScreenshotExpect.prototype.censorMatching(selector) -> ScreenshotExpect
selectoris a CSS selector with which you mean to ignore a part of the screenshot for comparison- For example,
phantesta.expect(page).censorMatching('.ignore-in-ui-test').toMatchScreenshot('name');
async ScreenshotExpect.prototype.censorRect(x, y, width, height) -> ScreenshotExpect
- takes parameters for a box (with 0,0 in the top left), and censors that box so that it is excluded from any comparison
- that is, the box censored by this method will contain pixels that can contain anything without failing the test
async ScreenshotExpect.prototype.includeOnlyRect(x, y, width, height) -> ScreenshotExpect
- takes parameters for a box (with 0,0 in the top left), and censors anything not in that box from being included in the image comparison
- if you include only multiple elements, their union is included and all other things are excluded
- if you don't specify anything to include only, everything is included by default
async ScreenshotExpect.prototype.includeOnlyMatching(selector) -> ScreenshotExpect
- finds all elements in the page matching
selectorand callsincludeOnlyRecton them.
async Phantesta.prototype.expectSame(name1, name2, boxes)
Passes if the screenshot name1 is the same as name2. Fails otherwise.
boxesis an array of objects defining regions to ignore in the comparison where each region is defined withx, andyof the top left corner, as well asw, andhfor width and height- e.g.
{ x: 100, y: 100, w: 100, h: 100 }for a region positioned at (100, 100) that is 100 pixels in width and height
async Phantesta.prototype.expectDiff(name1, name2, boxes)
Passes if the screenshot name1 is different than name2. Fails otherwise.
boxesis an array of objects defining regions to ignore in the comparison where each region is defined withx, andyof the top left corner, as well asw, andhfor width and height- e.g.
{ x: 100, y: 100, w: 100, h: 100 }for a region positioned at (100, 100) that is 100 pixels in width and height
Phantesta.prototype.group(groupName)
Change the current screenshot directory to a subdirectory named groupName.
Can be called multiple times.
Returns the current screenshot directory
Phantesta.prototype.group()
Change the current screenshot directory to the parent. Can be called multiple times.
If the current screenshot directory is the root screenshot directory, this has no effect.
Returns the current screenshot directory
NOTE: Place the call to group and ungroup inside
beforeEach and afterEach respectively when using jasmine.
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago