Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Adding Cypress tests to cover existing functional tests #912

Merged
merged 5 commits into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
loadPreview();
}

function loadPreview() {
function loadPreview(options) {
var token = localStorage.getItem('token');
var fileid = localStorage.getItem('fileid');

Expand All @@ -93,6 +93,7 @@
/* global Box */
var preview = new Box.Preview();
preview.show(fileid, token, {
...options,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These files aren't transpiled by Babel, so I believe this will fail in IE11.

container: ".preview-container",
});

Expand Down
5 changes: 4 additions & 1 deletion src/lib/Controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ class Controls {
constructor(container) {
this.containerEl = container;

const controlsWrapperEl = this.containerEl.appendChild(document.createElement('div'));
const controlsWrapperEl = document.createElement('div');
controlsWrapperEl.className = 'bp-controls-wrapper';
controlsWrapperEl.setAttribute('data-testid', 'controls-wrapper');
this.containerEl.appendChild(controlsWrapperEl);

this.controlsEl = controlsWrapperEl.appendChild(document.createElement('div'));
this.controlsEl.className = 'bp-controls';
Expand Down Expand Up @@ -198,6 +200,7 @@ class Controls {
button.setAttribute('aria-label', text);
button.setAttribute('title', text);
button.className = `${CONTROLS_BUTTON_CLASS} ${classList}`;
button.setAttribute('data-testid', text);
button.addEventListener('click', handler);

if (buttonContent) {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/PageControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const NEXT_PAGE = 'bp-next-page';

const pageNumTemplate = `
<div class='${CONTROLS_PAGE_NUM_WRAPPER_CLASS}'>
<span class=${CONTROLS_CURRENT_PAGE}>1</span>
<input type='number' pattern='[0-9]*' min='1' value='' size='3' class='${CONTROLS_PAGE_NUM_INPUT_CLASS}' />
<span class=${CONTROLS_CURRENT_PAGE} data-testid='current-page'>1</span>
<input type='number' pattern='[0-9]*' min='1' value='' size='3' class='${CONTROLS_PAGE_NUM_INPUT_CLASS}' data-testid='page-num-input'/>
<span class='bp-page-num-divider'>&nbsp;/&nbsp;</span>
<span class='${CONTROLS_TOTAL_PAGES}'>1</span>
</div>`.replace(/>\s*</g, '><');
Expand Down
8 changes: 4 additions & 4 deletions src/lib/shell.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@
</span>
<img class="bp-is-hidden bp-custom-logo"></img>
<div class="bp-header-btns">
<button class="bp-btn-plain bp-btn-annotate-draw bp-is-hidden">
<button class="bp-btn-plain bp-btn-annotate-draw bp-is-hidden" data-testid="draw-annotation">
<svg class="bp-btn-annotate-draw-enter" width="22" height="21" viewBox="0 0 14.88 14.88" focusable="false">
<path d="M11.65,6.64,5.11,13.17.06,14.94,1.83,9.89,8.37,3.35Zm1.41-1.41L9.78,1.94,11.37.35a1,1,0,0,1,1.41,0l1.87,1.87a1,1,0,0,1,0,1.41Z" transform="translate(-0.06 -0.06)" fill-rule="evenodd"/>
</svg>
</button>
<button class="bp-btn-plain bp-btn-annotate-point bp-is-hidden">
<button class="bp-btn-plain bp-btn-annotate-point bp-is-hidden" data-testid="point-annotation">
<svg width="22" height="21" viewBox="0 0 22 21" focusable="false">
<path d="M11 21l-4-4H1.99C.89 17 0 16.11 0 15V2C0 .895.89 0 1.99 0h18.02C21.11 0 22 .89 22 2v13c0 1.105-.89 2-1.99 2H15l-4 4zm-7-9.5c0-.276.228-.5.51-.5h8.98c.282 0 .51.232.51.5 0 .276-.228.5-.51.5H4.51c-.282 0-.51-.232-.51-.5zm0-3c0-.276.23-.5.5-.5h11c.276 0 .5.232.5.5 0 .276-.23.5-.5.5h-11c-.276 0-.5-.232-.5-.5zm0-3c0-.276.22-.5.498-.5h13.004c.275 0 .498.232.498.5 0 .276-.22.5-.498.5H4.498C4.223 6 4 5.768 4 5.5z" fill-rule="evenodd"/>
</svg>
</button>
<button class="bp-btn-plain bp-btn-print bp-is-hidden">
<button class="bp-btn-plain bp-btn-print bp-is-hidden" data-testid="print-preview">
<svg height="24" viewBox="0 0 24 24" width="24" focusable="false">
<path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
</button>
<button class="bp-btn-plain bp-btn-download bp-is-hidden">
<button class="bp-btn-plain bp-btn-download bp-is-hidden" data-testid="download-preview">
<svg height="24" viewBox="0 0 24 24" width="24" focusable="false">
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
<path d="M0 0h24v24H0z" fill="none"/>
Expand Down
1 change: 1 addition & 0 deletions src/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function createDownloadIframe() {
if (!iframe) {
iframe = document.createElement('iframe');
iframe.setAttribute('id', 'downloadiframe');
iframe.setAttribute('data-testid', 'downloadiframe');
iframe.style.display = 'none';
iframe = document.body.appendChild(iframe);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/viewers/media/MediaControls.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="bp-media-controls-wrapper">
<div class="bp-media-controls-wrapper" data-testid="media-controls-wrapper">
<div class="bp-media-time-scrubber-container" tabindex="0"></div>
<div class="bp-media-controls-container">
<button class="bp-media-controls-btn bp-media-playpause-icon">
Expand Down
108 changes: 108 additions & 0 deletions test/integration/document/Controls.e2e.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// <reference types="Cypress" />
describe('Preview Document Controls', () => {
const token = Cypress.env('ACCESS_TOKEN');
const fileId = Cypress.env('FILE_ID_DOC');

/* eslint-disable */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What rules are we breaking here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think jsdoc comments for the functions

const getPage = (pageNum) => cy.get(`.page[data-page-number=${pageNum}]`);
const showControls = () => {
// Hover over the preview to trigger the controls
cy.getByTestId('bp').trigger('mouseover');
// Assert that the controls are shown
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of code comments, but this logic seems pretty self-explanatory to me. Is a comment needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 will remove

cy.getByTestId('controls-wrapper').should('be.visible');
};
/* eslint-enable */

beforeEach(() => {
cy.visit('/');
// Show the preview
cy.showPreview(token, fileId);
});

it('Should zoom in and out', () => {
// Assert document content is present
cy.contains('The Content Platform for Your Apps');
// Get the current dimensions of the page
getPage(1).then(($page) => {
cy.wrap($page[0].scrollWidth).as('origWidth');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally want to avoid abbreviation where possible.

cy.wrap($page[0].scrollHeight).as('origHeight');
});

showControls();
// Click the zoom out button
cy.getByTestId('Zoom out').click();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a good use case for getByTitle.


getPage(1).then(($page) => {
const zoomedOutWidth = $page[0].scrollWidth;
const zoomedOutHeight = $page[0].scrollHeight;

cy.get('@origWidth').then((origWidth) => expect(origWidth).to.be.above(zoomedOutWidth));
cy.get('@origHeight').then((origHeight) => expect(origHeight).to.be.above(zoomedOutHeight));

cy.wrap(zoomedOutWidth).as('zoomedOutWidth');
cy.wrap(zoomedOutHeight).as('zoomedOutHeight');
});

// Hover over the preview to trigger the controls
cy.getByTestId('bp').trigger('mouseover');
// Assert that the controls are shown
cy.getByTestId('controls-wrapper').should('be.visible');
// Click the zoom out button
cy.getByTestId('Zoom in').click();

getPage(1).then(($page) => {
const zoomedInWidth = $page[0].scrollWidth;
const zoomedInHeight = $page[0].scrollHeight;

cy.get('@zoomedOutWidth').then((zoomedOutWidth) => expect(zoomedOutWidth).to.be.below(zoomedInWidth));
cy.get('@zoomedOutHeight').then((zoomedOutHeight) => expect(zoomedOutHeight).to.be.below(zoomedInHeight));
});
});

it('Should handle page navigation via buttons', () => {
getPage(1).should('be.visible');
cy.contains('The Content Platform for Your Apps');
cy.getByTestId('current-page').invoke('text').should('equal', '1');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: You can alias these elements for reuse later in the test rather than selecting them each time.


showControls();
cy.getByTestId('Next page').click();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should probably use contains or getByTitle for any natural language selectors, ideally.


getPage(2).should('be.visible');
cy.contains('Discover how your business can use Box Platform');
cy.getByTestId('current-page').invoke('text').should('equal', '2');

showControls();
cy.getByTestId('Previous page').click();

getPage(1).should('be.visible');
cy.contains('The Content Platform for Your Apps');
cy.getByTestId('current-page').invoke('text').should('equal', '1');
});

it('Should handle page navigation via input', () => {
getPage(1).should('be.visible');
cy.contains('The Content Platform for Your Apps');
cy.getByTestId('current-page').invoke('text').should('equal', '1');

showControls();
cy.getByTestId('Click to enter page number').click();
cy.getByTestId('page-num-input').should('be.visible').type('2').blur();
// cy.getByTestId('page-num-input').type('2').blur();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is intentional, but try to avoid commented code.


getPage(2).should('be.visible');
cy.contains('Discover how your business can use Box Platform');
cy.getByTestId('current-page').invoke('text').should('equal', '2');
});

// Fullscreen won't allow a non user gesture to trigger fullscreen
// There is an open issue for cypress to allow this
// https://github.com/cypress-io/cypress/issues/1213
//
// it('Should handle going fullscreen', () => {
// getPage(1).should('be.visible');
// cy.contains('The Content Platform for Your Apps');
// showControls();
// cy.getByTestId('Enter fullscreen').should('be.visible').click();
// cy.getByTestId('Exit fullscreen').should('be.visible');
// });
});
69 changes: 69 additions & 0 deletions test/integration/sanity/FileOptions.e2e.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// <reference types="Cypress" />
describe('Preview File Options', () => {
const token = Cypress.env('ACCESS_TOKEN');

const fileIdDoc = Cypress.env('FILE_ID_DOC');
const fileIdVideo = Cypress.env('FILE_ID_VIDEO');
const fileIdMp3 = Cypress.env('FILE_ID_MP3');

const fileOptions = {
[fileIdDoc]: {
startAt: {
value: 2,
unit: 'pages'
}
},
[fileIdVideo]: {
startAt: {
value: 15,
unit: 'seconds'
}
},
[fileIdMp3]: {
startAt: {
value: 3,
unit: 'seconds'
}
}
};

/* eslint-disable */
const getPage = (pageNum) => cy.get(`.page[data-page-number=${pageNum}]`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is used in more than one file, we should probably share it between them somehow.

const showMediaControls = () => {
// Hover over the preview to trigger the controls
cy.getByTestId('bp').trigger('mouseover');
// Assert that the controls are shown
return cy.getByTestId('media-controls-wrapper').should('be.visible');
};
/* eslint-enable */

beforeEach(() => {
cy.visit('/');
});

it('Should open document preview on the specified page', () => {
cy.showPreview(token, fileIdDoc, { fileOptions });

getPage(2).should('be.visible');
cy.contains('Discover how your business can use Box Platform');
cy.getByTestId('current-page').invoke('text').should('equal', '2');
});

it('Should open video(DASH) to the specified timestamp', () => {
cy.showPreview(token, fileIdVideo, { fileOptions });

showMediaControls().contains('0:15');
});

it('Should open video(MP4) to the specified timestamp', () => {
cy.showPreview(token, fileIdVideo, { fileOptions, viewers: { 'Dash': { disabled: true } } });

showMediaControls().contains('0:15');
});

it('Should open MP3 to the specified timestamp', () => {
cy.showPreview(token, fileIdMp3, { fileOptions });

showMediaControls().contains('0:03');
});
});
16 changes: 16 additions & 0 deletions test/integration/sanity/Header.e2d.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// <reference types="Cypress" />
describe('Preview Header', () => {
const token = Cypress.env('ACCESS_TOKEN');
const fileIdDoc = Cypress.env('FILE_ID_DOC');
const urlRegex = /https:\/\/dl[0-9]*\.boxcloud\.com.+\/download/;

beforeEach(() => {
cy.visit('/');
cy.showPreview(token, fileIdDoc, { showDownload: true });
});

it('Should be able to download the file', () => {
cy.getByTestId('download-preview').should('be.visible').click();
cy.getByTestId('downloadiframe').then((iframe) => expect(urlRegex.test(iframe[0].src)).to.be.true);
});
});
8 changes: 2 additions & 6 deletions test/integration/sanity/Sanity.e2e.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
// <reference types="Cypress" />
describe('Preview Sanity', () => {
let token;
const token = Cypress.env('ACCESS_TOKEN');
const fileId = Cypress.env('FILE_ID_DOC');

beforeEach(() => {
token = Cypress.env('ACCESS_TOKEN');
cy.visit('/');
});

it('Should load a document preview', () => {
const fileId = Cypress.env('FILE_ID_DOC');

// Show the preview
cy.showPreview(token, fileId);
// Wait for .bp to load viewer
cy.getByTestId('bp').should('have.class', 'bp-loaded')
// Assert document content is present
cy.contains('The Content Platform for Your Apps');
});
Expand Down
19 changes: 14 additions & 5 deletions test/support/commands.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
Cypress.Commands.add('getByTestId', (testId) => cy.get(`[data-testid="${testId}"]`));
Cypress.Commands.add('getByTitle', (title) => cy.get(`[title="${title}"]`));
Cypress.Commands.add('showPreview', (token, fileId) => {
cy.get('[data-testid="token"]').type(token);
cy.get('[data-testid="token-set"]').click();
cy.get('[data-testid="fileid"]').type(fileId);
cy.get('[data-testid="fileid-set"]').click();
Cypress.Commands.add('showPreview', (token, fileId, options) => {
cy.getByTestId('token').type(token);
cy.getByTestId('token-set').click();
cy.getByTestId('fileid').type(fileId);
cy.getByTestId('fileid-set').click();

if (options) {
cy.window().then((win) => {
win.loadPreview(options);
});
}

// Wait for .bp to load viewer
cy.getByTestId('bp').should('have.class', 'bp-loaded')
});