diff --git a/cypress/integration/back-to-top.spec.js b/cypress/integration/back-to-top.spec.js index e7e36c97..3d22d4ca 100644 --- a/cypress/integration/back-to-top.spec.js +++ b/cypress/integration/back-to-top.spec.js @@ -1,34 +1,34 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ const url = 'api/'; describe('Back-to-top button tests', function() { beforeEach(function() { cy.visit(url); }); it('should be hidden when on top', function() { cy.get('#back-to-top').should('not.be.visible'); }); it('should be visible when scrolled down', function() { cy.scrollTo('bottom') .get('#back-to-top') .should('be.visible'); }); it('should scroll to top when clicked', function() { cy.scrollTo('bottom') .get('#back-to-top') .click() .window() - .then((window) => { - assert.equal(window.scrollY, 0); + .then(win => { + assert.equal(win.scrollY, 0); }); }); }); diff --git a/cypress/integration/code-highlighting.spec.js b/cypress/integration/code-highlighting.spec.js index abafc7a3..881619c9 100644 --- a/cypress/integration/code-highlighting.spec.js +++ b/cypress/integration/code-highlighting.spec.js @@ -1,95 +1,94 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ import {random} from '../utils'; const $ = Cypress.$; let origin; const lineStart = 32; const lineEnd = 42; let url; describe('Code highlighting tests', function() { before(function() { origin = this.origin[0]; url = this.Urls.browse_origin_content(origin.url, origin.content[0].path); }); it('should highlight source code and add line numbers', function() { cy.visit(url); cy.get('.hljs-ln-numbers').then(lnNumbers => { - cy.get('.hljs-ln-code').then(lnCode => { - assert.equal(lnNumbers.length, lnCode.length); - }); + cy.get('.hljs-ln-code') + .should('have.length', lnNumbers.length); }); }); it('should emphasize source code lines based on url fragment', function() { cy.visit(`${url}/#L${lineStart}-L${lineEnd}`); cy.get('.hljs-ln-line').then(lines => { for (let line of lines) { const lineElt = $(line); const lineNumber = parseInt(lineElt.data('line-number')); if (lineNumber >= lineStart && lineNumber <= lineEnd) { assert.notEqual(lineElt.css('background-color'), 'rgba(0, 0, 0, 0)'); } else { assert.equal(lineElt.css('background-color'), 'rgba(0, 0, 0, 0)'); } } }); }); it('should emphasize a line by clicking on its number', function() { cy.visit(url); cy.get('.hljs-ln-numbers').then(lnNumbers => { const lnNumber = lnNumbers[random(0, lnNumbers.length)]; const lnNumberElt = $(lnNumber); assert.equal(lnNumberElt.css('background-color'), 'rgba(0, 0, 0, 0)'); const line = parseInt(lnNumberElt.data('line-number')); cy.get(`.hljs-ln-numbers[data-line-number="${line}"]`) .click() .then(() => { assert.notEqual(lnNumberElt.css('background-color'), 'rgba(0, 0, 0, 0)'); }); }); }); it('should emphasize a range of lines by clicking on two line numbers and holding shift', function() { cy.visit(url); cy.get(`.hljs-ln-numbers[data-line-number="${lineStart}"]`) .click() .get(`body`) .type(`{shift}`, { release: false }) .get(`.hljs-ln-numbers[data-line-number="${lineEnd}"]`) .click() .get('.hljs-ln-line') .then(lines => { for (let line of lines) { const lineElt = $(line); const lineNumber = parseInt(lineElt.data('line-number')); if (lineNumber >= lineStart && lineNumber <= lineEnd) { assert.notEqual(lineElt.css('background-color'), 'rgba(0, 0, 0, 0)'); } else { assert.equal(lineElt.css('background-color'), 'rgba(0, 0, 0, 0)'); } } }); }); it('should remove emphasized lines when clicking anywhere in code', function() { cy.visit(`${url}/#L${lineStart}-L${lineEnd}`); cy.get(`.hljs-ln-code[data-line-number="1"]`) .click() .get('.hljs-ln-line') .should('have.css', 'background-color', 'rgba(0, 0, 0, 0)'); }); }); diff --git a/cypress/integration/directory.spec.js b/cypress/integration/directory.spec.js index 67e0f02d..f09a7e6b 100644 --- a/cypress/integration/directory.spec.js +++ b/cypress/integration/directory.spec.js @@ -1,77 +1,75 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ -import {httpGetJson} from '../utils'; - const $ = Cypress.$; let origin; let url; let dirs = []; let files = []; describe('Directory Tests', function() { before(function() { origin = this.origin[0]; url = this.Urls.browse_origin_directory(origin.url); for (let entry of origin.dirContent) { if (entry.type === 'file') { files.push(entry); } else { dirs.push(entry); } } }); beforeEach(function() { cy.visit(url); }); it('should display all files and directories', function() { cy.get('.swh-directory') .should('have.length', dirs.length) .and('be.visible'); cy.get('.swh-content') .should('have.length', files.length) .and('be.visible'); }); it('should display sizes for files', function() { cy.get('.swh-content') .parent('tr') .then((rows) => { for (let row of rows) { let text = $(row).children('td').eq(2).text(); expect(text.trim()).to.not.be.empty; } }); }); it('should display readme when it is present', function() { cy.get('#readme-panel > .card-body') .should('be.visible') .and('have.class', 'swh-showdown') .and('not.be.empty') .and('not.contain', 'Readme bytes are not available'); }); it('should open subdirectory when clicked', function() { cy.get('.swh-directory') .first() .children('a') .click(); cy.url() .should('include', url + dirs[0]['name']); cy.get('.swh-directory-table') .should('be.visible'); }); }); diff --git a/cypress/integration/errors.spec.js b/cypress/integration/errors.spec.js index 0b7bba06..5c073496 100644 --- a/cypress/integration/errors.spec.js +++ b/cypress/integration/errors.spec.js @@ -1,150 +1,148 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ -import {httpGetJson} from '../utils'; - let origin; const invalidChecksum = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; const invalidPageUrl = '/invalidPath'; function urlShouldShowError(url, error) { cy.visit(url, { failOnStatusCode: false }); cy.get('.swh-http-error') .should('be.visible'); cy.get('.swh-http-error-code') .should('contain', error.code); cy.get('.swh-http-error-desc') .should('contain', error.msg); } describe('Test Errors', function() { before(function() { origin = this.origin[0]; }); it('should show navigation buttons on error page', function() { cy.visit(invalidPageUrl, { failOnStatusCode: false }); cy.get('a[onclick="window.history.back();"]') .should('be.visible'); cy.get('a[href="/"') .should('be.visible'); }); context('For unarchived repositories', function() { it('should display NotFoundExc for unarchived repo', function() { const url = this.Urls.browse_origin_directory(this.unarchivedRepo.url); urlShouldShowError(url, { code: '404', msg: 'NotFoundExc: Origin with url ' + this.unarchivedRepo.url + ' not found!' }); }); it('should display NotFoundExc for unarchived content', function() { const url = this.Urls.browse_content(`sha1_git:${this.unarchivedRepo.content[0].sha1git}`); urlShouldShowError(url, { code: '404', msg: 'NotFoundExc: Content with sha1_git checksum equals to ' + this.unarchivedRepo.content[0].sha1git + ' not found!' }); }); it('should display NotFoundExc for unarchived directory sha1git', function() { const url = this.Urls.browse_directory(this.unarchivedRepo.rootDirectory); urlShouldShowError(url, { code: '404', msg: 'NotFoundExc: Directory with sha1_git ' + this.unarchivedRepo.rootDirectory + ' not found' }); }); it('should display NotFoundExc for unarchived revision sha1git', function() { const url = this.Urls.browse_revision(this.unarchivedRepo.revision); urlShouldShowError(url, { code: '404', msg: 'NotFoundExc: Revision with sha1_git ' + this.unarchivedRepo.revision + ' not found.' }); }); it('should display NotFoundExc for unarchived snapshot sha1git', function() { const url = this.Urls.browse_snapshot(this.unarchivedRepo.snapshot); urlShouldShowError(url, { code: '404', msg: 'Snapshot with id ' + this.unarchivedRepo.snapshot + ' not found!' }); }); }); context('For archived repositories', function() { before(function() { const url = this.Urls.browse_origin_directory(origin.url); cy.visit(url); }); it('should display NotFoundExc for invalid directory from archived repo', function() { const rootDir = this.Urls.browse_origin_directory(origin.url); const subDir = rootDir + origin.invalidSubDir; urlShouldShowError(subDir, { code: '404', msg: 'NotFoundExc: Directory entry with path ' + origin.invalidSubDir + ' from ' + origin.rootDirectory + ' not found' }); }); it(`should display NotFoundExc for incorrect origin_url with correct content hash`, function() { const url = this.Urls.browse_content(`sha1_git:${origin.content[0].sha1git}`) + `?origin_url=${this.unarchivedRepo.url}`; urlShouldShowError(url, { code: '404', msg: 'The Software Heritage archive has a content ' + 'with the hash you provided but the origin ' + 'mentioned in your request appears broken: ' + this.unarchivedRepo.url + '. ' + 'Please check the URL and try again.\n\n' + 'Nevertheless, you can still browse the content ' + 'without origin information: ' + '/browse/content/sha1_git:' + origin.content[0].sha1git + '/' }); }); }); context('For invalid data', function() { it(`should display 400 for invalid checksum for directory, snapshot, revision, content`, function() { const types = ['directory', 'snapshot', 'revision', 'content']; for (let type of types) { const url = this.Urls[`browse_${type}`](invalidChecksum); urlShouldShowError(url, { code: '400', msg: 'BadInputExc: Invalid checksum query string ' + invalidChecksum }); } }); it('should show 404 error for invalid path', function() { urlShouldShowError(invalidPageUrl, { code: '404', msg: 'The resource ' + invalidPageUrl + ' could not be found on the server.' }); }); }); }); diff --git a/cypress/integration/layout.spec.js b/cypress/integration/layout.spec.js index 35339b31..19e3804e 100644 --- a/cypress/integration/layout.spec.js +++ b/cypress/integration/layout.spec.js @@ -1,49 +1,49 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ const url = '/'; describe('Test top-bar', function() { it('should should contain all navigation links', function() { cy.visit(url); - cy.get('.swh-top-bar > ul > li > a') + cy.get('.swh-top-bar a') .should('have.length', 5) .and('be.visible') .and('have.attr', 'href'); }); it('should show donate button on lg screen', function() { cy.visit(url); cy.get('.swh-donate-link') .should('be.visible'); }); it('should hide donate button on sm screen', function() { cy.viewport(600, 800); cy.visit(url); cy.get('.swh-donate-link') .should('not.be.visible'); }); }); describe('Test footer', function() { beforeEach(function() { cy.visit(url); }); it('should be visible', function() { cy.get('footer') .should('be.visible'); }); it('should have correct copyright years', function() { const currentYear = new Date().getFullYear(); const copyrightText = '(C) 2015–' + currentYear.toString(); cy.get('footer') .should('contain', copyrightText); }); }); diff --git a/cypress/integration/sidebar.spec.js b/cypress/integration/sidebar.spec.js index 8cb39fc7..6750f09e 100644 --- a/cypress/integration/sidebar.spec.js +++ b/cypress/integration/sidebar.spec.js @@ -1,85 +1,77 @@ /** * Copyright (C) 2019 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ const url = '/'; describe('Sidebar tests On Large Screen', function() { beforeEach(function() { cy.visit(url, { onBeforeLoad: (win) => { win.localStorage.clear(); } }); }); it('should toggle sidebar when swh-push-menu is clicked', function() { cy.get('.swh-push-menu') - .click() - .then(() => { - cy.get('body') - .should('have.class', 'sidebar-collapse') - .get('.nav-link > p') - .should('have.css', 'opacity', '0'); - }) - .get('.swh-push-menu') - .click() - .then(() => { - cy.get('body') - .should('have.class', 'sidebar-open') - .get('.nav-link > p') - .should('not.have.css', 'opacity', '0'); - }); + .click(); + cy.get('body') + .should('have.class', 'sidebar-collapse') + .get('.nav-link > p') + .should('not.be.visible'); + + cy.get('.swh-push-menu') + .click(); + cy.get('body') + .should('have.class', 'sidebar-open') + .get('.nav-link > p') + .should('be.visible'); }); it('should have less width when collapsed compared to open', function() { - let collapsedWidth, expandedWidth; + let collapseWidth; cy.get('.swh-push-menu') .click() - .wait(250) .get('.swh-sidebar') - .should('have.css', 'width') + .wait(250) + .invoke('width') .then((width) => { - collapsedWidth = parseInt(width); + collapseWidth = width; }) .get('.swh-push-menu') .click() - .wait(250) .get('.swh-sidebar') - .should('have.css', 'width') - .then((width) => { - expandedWidth = parseInt(width); - }) - .then(() => { - assert.isBelow(collapsedWidth, expandedWidth); + .wait(250) + .invoke('width') + .then(openWidth => { + assert.isBelow(collapseWidth, openWidth); }); }); }); describe('Sidebar Tests on small screens', function() { beforeEach(function() { cy.viewport('iphone-6'); cy.visit(url); }); it('should be collapsed by default', function() { cy.get('.swh-sidebar') .should('not.be.visible'); }); it('should toggle sidebar when swh-push-menu is clicked', function() { cy.get('.swh-push-menu') .click() - .wait(250) .get('.swh-sidebar') .should('be.visible') .get('#sidebar-overlay') .click({force: true}) - .wait(250) .get('.swh-sidebar') .should('not.be.visible'); }); });