Skip to content

Commit

Permalink
chore: Compass Cypress tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed Oct 27, 2024
1 parent 22c38db commit 80853e4
Show file tree
Hide file tree
Showing 28 changed files with 213 additions and 48 deletions.
6 changes: 6 additions & 0 deletions build/templates/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ export const packageJson = (pkg: any) => {
main: 'index.cjs',
module: 'index.module.js',
types: 'index.d.ts',
exports: {
'.': {
import: './index.module.js',
require: './index.cjs',
},
},
license: 'MIT',
repository: {
type: 'git',
Expand Down
86 changes: 86 additions & 0 deletions cypress/e2e/compass.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { CompassPlugin, CompassPluginConfig } from '@photo-sphere-viewer/compass-plugin';
import { getPlugin, getViewer, waitViewerReady } from '../utils';

describe('compass', () => {
beforeEach(() => {
cy.visit('e2e/compass.html');
waitViewerReady();
// createBaseSnapshot();
});

it('should have a compass', () => {
cy.get('.psv-compass')
.should('be.visible')
.compareScreenshots('base');
});

it('should pan & zoom', () => {
getViewer('rotate 90deg')
.then(viewer => viewer.rotate({ pitch: 0, yaw: '90deg' }))
.wait(200);

cy.get('.psv-compass').compareScreenshots('rotate');

getViewer('zoom 100%')
.then(viewer => viewer.zoom(100))
.wait(200);

cy.get('.psv-compass').compareScreenshots('zoom');
});

it('should show navigation cone', () => {
cy.get('.psv-compass').then(compass => {
const { x, y, width, height } = compass[0].getBoundingClientRect();

// center-right
const enterPoint = { clientX: x + width, clientY: y + height / 2 };
// above bottom-center
const clickPoint = { clientX: x + width / 2, clientY: y + height - 20 };
// bottom-center
const leavePoint = { clientX: x + width / 2, clientY: y + height };

cy.wrap(compass, { log: false })
.trigger('mouseenter', enterPoint)
.compareScreenshots('navigation-1')
.trigger('mousemove', clickPoint)
.compareScreenshots('navigation-2')
.trigger('mousedown', clickPoint)
.trigger('mouseup', clickPoint)
.trigger('mouseleave', leavePoint)
.compareScreenshots('navigation-3');
});

cy.wait(200);

getViewer('check position').then(viewer => {
expect(viewer.getPosition()).to.deep.eq({ yaw: Math.PI, pitch: 0 });
});
});

Object.entries({
coneColor: '#00000055',
navigationColor: 'rgba(0, 255, 0, 0.5)',
size: '300px',
backgroundSvg: '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="50" fill="rgba(0, 0, 0, .5)"/></svg>',
} satisfies CompassPluginConfig).forEach(([key, value]) => {
it(`should set the ${key}`, () => {
getPlugin<CompassPlugin>('compass', `set ${key}`)
.then(compass => compass.setOption(key as any, value))
.wait(200);

if (key === 'nabigationColor') {
cy.get('.psv-compass').then(compass => {
const { x, y, width, height } = compass[0].getBoundingClientRect();

cy.wrap(compass, { log: false })
.trigger('mousemove', { clientX: x + width / 2, clientY: y + height - 20 })
.compareScreenshots(`set-${key}`)
.trigger('mouseleave');
});
} else {
cy.get('.psv-compass').compareScreenshots(`set-${key}`);
}
});
});

});
51 changes: 26 additions & 25 deletions cypress/e2e/navbar.cy.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { callViewer, waitViewerReady } from '../utils';
import { getViewer, waitViewerReady } from '../utils';

describe('navbar', () => {
beforeEach(() => {
localStorage.photoSphereViewer_touchSupport = 'false';
cy.visit('e2e/navbar.html');
waitViewerReady();
// createBaseSnapshot();
});

it('should have a navbar', () => {
cy.get('.psv-navbar')
.should('be.visible')
.compareSnapshot('base');
.compareScreenshots('base');
});

it('should have a custom button', () => {
Expand All @@ -27,13 +28,13 @@ describe('navbar', () => {
it('should update the caption', () => {
cy.get('.psv-caption-content').should('have.text', 'Parc national du Mercantour © Damien Sorel');

callViewer('change caption via options', viewer => viewer.setOption('caption', '<strong>Name:</strong> Lorem Ipsum'));
getViewer('change caption via options').then(viewer => viewer.setOption('caption', '<strong>Name:</strong> Lorem Ipsum'));

cy.get('.psv-caption-content').should('have.text', 'Name: Lorem Ipsum');

cy.get('.psv-navbar').compareSnapshot('update-caption');
cy.get('.psv-navbar').compareScreenshots('update-caption');

callViewer('change caption via API', viewer => viewer.navbar.setCaption('Loading...'));
getViewer('change caption via API').then(viewer => viewer.navbar.setCaption('Loading...'));

cy.get('.psv-caption-content').should('have.text', 'Loading...');
});
Expand All @@ -47,7 +48,7 @@ describe('navbar', () => {
.should('be.visible')
.should('include.text', 'Parc national du Mercantour © Damien Sorel')
.should('include.text', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit')
.compareSnapshot('description');
.compareScreenshots('description');
});

// does not work in headless mode
Expand All @@ -66,18 +67,18 @@ describe('navbar', () => {
viewportWidth: 800,
viewportHeight: 900,
}, () => {
callViewer('remove description', viewer => viewer.setOption('description', null));
getViewer('remove description').then(viewer => viewer.setOption('description', null));

cy.get('.psv-caption-content').should('not.be.visible');

cy.get('.psv-navbar').compareSnapshot('no-caption');
cy.get('.psv-navbar').compareScreenshots('no-caption');

cy.get('.psv-description-button').click();

cy.get('.psv-notification-content')
.should('be.visible')
.should('have.text', 'Parc national du Mercantour © Damien Sorel')
.compareSnapshot('caption-notification');
.compareScreenshots('caption-notification');

cy.get('.psv-description-button').click();

Expand Down Expand Up @@ -108,7 +109,7 @@ describe('navbar', () => {
cy.get(visible).should('be.visible');
});

cy.get('.psv-navbar').compareSnapshot('with-menu');
cy.get('.psv-navbar').compareScreenshots('with-menu');

cy.get('.psv-menu-button').click();

Expand All @@ -120,7 +121,7 @@ describe('navbar', () => {
cy.contains('Download').should('be.visible');
cy.contains('Click me').should('be.visible');
})
.compareSnapshot('menu-content');
.compareScreenshots('menu-content');

cy.get('.psv-panel-close-button').click();

Expand Down Expand Up @@ -167,17 +168,17 @@ describe('navbar', () => {
fullscreen: 'Plein écran',
myButton: 'Cliquez ici',
};
callViewer('translate to french', viewer => viewer.setOption('lang', fr));
getViewer('translate to french').then(viewer => viewer.setOption('lang', fr));

assertTitles(fr);
});

it('should hide the navbar', () => {
callViewer('hide navbar', viewer => viewer.navbar.hide());
getViewer('hide navbar').then(viewer => viewer.navbar.hide());

cy.get('.psv-navbar').should('not.be.visible');

callViewer('show navbar', viewer => viewer.navbar.show());
getViewer('show navbar').then(viewer => viewer.navbar.show());

cy.get('.psv-navbar').should('be.visible');
});
Expand All @@ -193,44 +194,44 @@ describe('navbar', () => {
});
}

callViewer('change buttons via options', viewer => viewer.setOption('navbar', 'zoom move'));
getViewer('change buttons via options').then(viewer => viewer.setOption('navbar', 'zoom move'));

assertButtons(['Zoom out', 'Zoom in', 'Move left', 'Move right', 'Move up', 'Move down']);

cy.get('.psv-navbar').compareSnapshot('update-buttons');
cy.get('.psv-navbar').compareScreenshots('update-buttons');

callViewer('change buttons via API', viewer => viewer.navbar.setButtons(['download', 'fullscreen']));
getViewer('change buttons via API').then(viewer => viewer.navbar.setButtons(['download', 'fullscreen']));

assertButtons(['Download', 'Fullscreen']);
});

it('should hide a button', () => {
callViewer('hide fullscreen button', viewer => viewer.navbar.getButton('fullscreen').hide());
getViewer('hide fullscreen button').then(viewer => viewer.navbar.getButton('fullscreen').hide());

cy.get('.psv-fullscreen-button').should('not.be.visible');

cy.get('.psv-navbar').compareSnapshot('hide-button');
cy.get('.psv-navbar').compareScreenshots('hide-button');

callViewer('show fullscreen button', viewer => viewer.navbar.getButton('fullscreen').show());
getViewer('show fullscreen button').then(viewer => viewer.navbar.getButton('fullscreen').show());

cy.get('.psv-fullscreen-button').should('be.visible');
});

it('should disable a button', () => {
callViewer('disable download button', viewer => viewer.navbar.getButton('download').disable());
getViewer('disable download button').then(viewer => viewer.navbar.getButton('download').disable());

cy.get('.psv-download-button').should('have.class', 'psv-button--disabled');

cy.get('.psv-navbar').compareSnapshot('disable-button');
cy.get('.psv-navbar').compareScreenshots('disable-button');

callViewer('enable download button', viewer => viewer.navbar.getButton('download').enable());
getViewer('enable download button').then(viewer => viewer.navbar.getButton('download').enable());

cy.get('.psv-download-button').should('not.have.class', 'psv-button--disabled');
});

it('should display a custom element', () => {
cy.document().then(document => {
callViewer('set custom element', viewer => viewer.navbar.setButtons([
getViewer('set custom element').then(viewer => viewer.navbar.setButtons([
{
content: document.createElement('custom-navbar-button'),
}
Expand All @@ -246,6 +247,6 @@ describe('navbar', () => {
cy.get('#value').should('have.text', '50');
});

cy.get('.psv-custom-button').compareSnapshot('custom-element');
cy.get('.psv-custom-button').compareScreenshots('custom-element');
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/base/cypress/e2e/navbar.cy.ts/base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/base/cypress/e2e/navbar.cy.ts/hide-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/base/cypress/e2e/navbar.cy.ts/no-caption.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified cypress/snapshots/base/cypress/e2e/navbar.cy.ts/with-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 33 additions & 17 deletions cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
import 'cypress-real-events';
import 'cypress-mochawesome-reporter/register';
import 'cypress-real-events';
import { addCompareSnapshotCommand } from 'cypress-visual-regression/dist/command';

addCompareSnapshotCommand({
errorThreshold: 0.1,
errorThreshold: 0.01,
failSilently: !Cypress.config('isInteractive'),
});

if (!Cypress.config('isInteractive')) {
Cypress.Commands.overwrite('compareSnapshot', (originalFn, name, options = {}) => {
return originalFn(name, options)
.then(result => {
if (result.images.diff) {
// @ts-ignore
Cypress.Mochawesome.context.push({ title: 'Visual regression diff', value: 'data:image/png;base64,' + result.images.diff });
}
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
interface Chainable {
compareScreenshots(name: string, options?: { errorThreshold?: number, hideViewer?: boolean }): Chainable<JQuery<HTMLElement>>;
}
}
}

if (result.error) {
throw new Error(result.error);
}
Cypress.Commands.add('compareScreenshots', { prevSubject: ['element'] }, (subject, name, options = {}) => {
if (options.hideViewer !== false) {
cy.get('.psv-canvas-container', { log: false }).then(container => container.hide());
}

return result;
});
});
}
cy.wrap(subject, { log: false }).compareSnapshot(name, options)
.then((result) => {
if (result.images.diff) {
// @ts-ignore
Cypress.Mochawesome.context.push({ title: 'Visual regression diff', value: 'data:image/png;base64,' + result.images.diff });
}

if (result.error) {
throw new Error(result.error);
}

if (options.hideViewer !== false) {
return cy.get('.psv-canvas-container', { log: false }).then(container => container.show());
}
});

return cy.wrap(subject, { log: false });
});
18 changes: 14 additions & 4 deletions cypress/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Viewer } from '@photo-sphere-viewer/core';
import type { AbstractPlugin, Viewer } from '@photo-sphere-viewer/core';

export function waitViewerReady() {
callViewer('wait ready', viewer => {
getViewer('wait ready').then(viewer => {
return new Promise(resolve => {
viewer.addEventListener('ready', () => {
setTimeout(resolve, 200);
Expand All @@ -10,9 +10,19 @@ export function waitViewerReady() {
});
}

export function callViewer(log: string, cb: (viewer: Viewer) => void) {
export function getViewer(log: string): Cypress.Chainable<Viewer> {
cy.log(`Viewer: ${log}`);
cy.window({ log: false }).its('viewer', { log: false }).then(cb);
return cy.window({ log: false })
.its('viewer', { log: false });
}

export function getPlugin<T extends AbstractPlugin<any>>(id: string, log: string | false): Cypress.Chainable<T> {
if (log !== false) {
cy.log(`${id}: ${log}`);
}
return cy.window({ log: false })
.its('viewer', { log: false })
.then(viewer => viewer.getPlugin(id));
}

export function createBaseSnapshot() {
Expand Down
Loading

0 comments on commit 80853e4

Please sign in to comment.