diff options
author | Michael Foiani <mfoiani2019@communityschoolnaples.org> | 2018-07-25 19:38:43 -0400 |
---|---|---|
committer | Michael Foiani <mfoiani2019@communityschoolnaples.org> | 2018-07-25 19:38:43 -0400 |
commit | 3c09a0a91488e182f521b0cd39017cb5bc781a83 (patch) | |
tree | bc26d401b97f13169f3becdfe03bba6fd0f34353 /test |
Initial commit. Added pwa starter kit to project for the application.
Diffstat (limited to 'test')
16 files changed, 507 insertions, 0 deletions
diff --git a/test/integration/router.js b/test/integration/router.js new file mode 100644 index 0000000..212565a --- /dev/null +++ b/test/integration/router.js @@ -0,0 +1,101 @@ +/** +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +*/ + +const puppeteer = require('puppeteer'); +const expect = require('chai').expect; +const {startServer} = require('polyserve'); +const path = require('path'); +const appUrl = 'http://127.0.0.1:4444'; + +describe('routing tests', function() { + let polyserve, browser, page; + + before(async function() { + polyserve = await startServer({port:4444, root:path.join(__dirname, '../..'), moduleResolution:'node'}); + }); + + after((done) => polyserve.close(done)); + + beforeEach(async function() { + browser = await puppeteer.launch(); + page = await browser.newPage(); + }); + + afterEach(() => browser.close()); + + it('the page selector switches pages', async function() { + await page.goto(`${appUrl}`); + await page.waitForSelector('my-app', {visible: true}); + + await testNavigation(page, 'view2', 'View Two'); + await testNavigation(page, 'view3', 'View Three'); + await testNavigation(page, 'view1', 'View One'); + }); + + it('the page selector switches pages in a different way', async function() { + await page.goto(`${appUrl}`); + await page.waitForSelector('my-app', {visible: true}); + + // Setup + await page.evaluate(() => { + window.deepQuerySelector = function(query) { + const parts = query.split('::shadow'); + let el = document; + for (let i = 0; i < parts.length; i++) { + el = el.querySelector(parts[i]); + if (i % 2 === 0) { + el = el.shadowRoot; + } + } + return el === document ? null : el; + } + console.log(window.deepQuerySelector); + }); + + await testNavigationInADifferentWay(page, 'view2', 'View Two'); + await testNavigationInADifferentWay(page, 'view3', 'View Three'); + await testNavigationInADifferentWay(page, 'view1', 'View One'); + }); +}); + +async function testNavigation(page, href, linkText) { + // Shadow DOM helpers. + const getShadowRootChildProp = (el, childSelector, prop) => { + return el.shadowRoot.querySelector(childSelector)[prop]; + }; + const doShadowRootClick = (el, childSelector) => { + return el.shadowRoot.querySelector(childSelector).click(); + }; + + const selector = `a[href="/${href}"]`; + const shadowSelector = `a[href="/${href}"]`; + + // Does the link say the right thing? + const myApp = await page.$('my-app'); + const myText = await page.evaluate(getShadowRootChildProp, myApp, selector, 'textContent'); + expect(await myText).equal(linkText); + + // Does the click take you to the right page? + await page.evaluate(doShadowRootClick, myApp, selector); + const newUrl = await page.evaluate('window.location.href') + expect(newUrl).equal(`${appUrl}/${href}`); +} + +async function testNavigationInADifferentWay(page, href, linkText) { + const query = `my-app::shadow a[href="/${href}"]`; + + const linkHandle = await page.evaluateHandle((query) => window.deepQuerySelector(query), query); + const text = await page.evaluate((el) => el.textContent, linkHandle); + expect(text).equal(linkText); + + await linkHandle.click(); + let newUrl = await page.evaluate('window.location.href') + expect(newUrl).equal(`${appUrl}/${href}`); +} diff --git a/test/integration/screenshots-baseline/narrow/batmanNotAView.png b/test/integration/screenshots-baseline/narrow/batmanNotAView.png Binary files differnew file mode 100644 index 0000000..31d9be3 --- /dev/null +++ b/test/integration/screenshots-baseline/narrow/batmanNotAView.png diff --git a/test/integration/screenshots-baseline/narrow/index.png b/test/integration/screenshots-baseline/narrow/index.png Binary files differnew file mode 100644 index 0000000..810529b --- /dev/null +++ b/test/integration/screenshots-baseline/narrow/index.png diff --git a/test/integration/screenshots-baseline/narrow/view1.png b/test/integration/screenshots-baseline/narrow/view1.png Binary files differnew file mode 100644 index 0000000..810529b --- /dev/null +++ b/test/integration/screenshots-baseline/narrow/view1.png diff --git a/test/integration/screenshots-baseline/narrow/view2.png b/test/integration/screenshots-baseline/narrow/view2.png Binary files differnew file mode 100644 index 0000000..695d8b0 --- /dev/null +++ b/test/integration/screenshots-baseline/narrow/view2.png diff --git a/test/integration/screenshots-baseline/narrow/view3.png b/test/integration/screenshots-baseline/narrow/view3.png Binary files differnew file mode 100644 index 0000000..b524cb7 --- /dev/null +++ b/test/integration/screenshots-baseline/narrow/view3.png diff --git a/test/integration/screenshots-baseline/regenerate.js b/test/integration/screenshots-baseline/regenerate.js new file mode 100644 index 0000000..4fd5305 --- /dev/null +++ b/test/integration/screenshots-baseline/regenerate.js @@ -0,0 +1,72 @@ +/** +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +*/ + +const puppeteer = require('puppeteer'); +const {startServer} = require('polyserve'); +const path = require('path'); +const fs = require('fs'); +const baselineDir = `${process.cwd()}/test/integration/screenshots-baseline`; + +describe('🎁 regenerate screenshots', function() { + let polyserve, browser, page; + + before(async function() { + polyserve = await startServer({port:4444, root:path.join(__dirname, '../../..'), moduleResolution:'node'}); + + // Create the test directory if needed. + if (!fs.existsSync(baselineDir)){ + fs.mkdirSync(baselineDir); + } + // And it's subdirectories. + if (!fs.existsSync(`${baselineDir}/wide`)){ + fs.mkdirSync(`${baselineDir}/wide`); + } + if (!fs.existsSync(`${baselineDir}/narrow`)){ + fs.mkdirSync(`${baselineDir}/narrow`); + } + }); + + after((done) => polyserve.close(done)); + + beforeEach(async function() { + browser = await puppeteer.launch(); + page = await browser.newPage(); + }); + + afterEach(() => browser.close()); + + it('did it', async function() { + return generateBaselineScreenshots(page); + }); +}); + +async function generateBaselineScreenshots(page) { + const breakpoints = [ + {width: 800, height: 600}, + {width: 375, height: 667}]; + const prefixes = ['wide', 'narrow']; + + for (let i = 0; i < prefixes.length; i++) { + const prefix = prefixes[i]; + console.log(prefix + '...'); + page.setViewport(breakpoints[i]); + // Index. + await page.goto('http://127.0.0.1:4444/'); + await page.screenshot({path: `${baselineDir}/${prefix}/index.png`}); + // Views. + for (let i = 1; i <= 3; i++) { + await page.goto(`http://127.0.0.1:4444/view${i}`); + await page.screenshot({path: `${baselineDir}/${prefix}/view${i}.png`}); + } + // 404. + await page.goto('http://127.0.0.1:4444/batmanNotAView'); + await page.screenshot({path: `${baselineDir}/${prefix}/batmanNotAView.png`}); + } +} diff --git a/test/integration/screenshots-baseline/wide/batmanNotAView.png b/test/integration/screenshots-baseline/wide/batmanNotAView.png Binary files differnew file mode 100644 index 0000000..c70b4ed --- /dev/null +++ b/test/integration/screenshots-baseline/wide/batmanNotAView.png diff --git a/test/integration/screenshots-baseline/wide/index.png b/test/integration/screenshots-baseline/wide/index.png Binary files differnew file mode 100644 index 0000000..211846f --- /dev/null +++ b/test/integration/screenshots-baseline/wide/index.png diff --git a/test/integration/screenshots-baseline/wide/view1.png b/test/integration/screenshots-baseline/wide/view1.png Binary files differnew file mode 100644 index 0000000..211846f --- /dev/null +++ b/test/integration/screenshots-baseline/wide/view1.png diff --git a/test/integration/screenshots-baseline/wide/view2.png b/test/integration/screenshots-baseline/wide/view2.png Binary files differnew file mode 100644 index 0000000..324b4d6 --- /dev/null +++ b/test/integration/screenshots-baseline/wide/view2.png diff --git a/test/integration/screenshots-baseline/wide/view3.png b/test/integration/screenshots-baseline/wide/view3.png Binary files differnew file mode 100644 index 0000000..fc81e20 --- /dev/null +++ b/test/integration/screenshots-baseline/wide/view3.png diff --git a/test/integration/visual.js b/test/integration/visual.js new file mode 100644 index 0000000..f4410f9 --- /dev/null +++ b/test/integration/visual.js @@ -0,0 +1,147 @@ +/** +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +*/ + +const puppeteer = require('puppeteer'); +const expect = require('chai').expect; +const {startServer} = require('polyserve'); +const path = require('path'); +const fs = require('fs'); +const PNG = require('pngjs').PNG; +const pixelmatch = require('pixelmatch'); + +const currentDir = `${process.cwd()}/test/integration/screenshots-current`; +const baselineDir = `${process.cwd()}/test/integration/screenshots-baseline`; + +describe('👀 page screenshots are correct', function() { + let polyserve, browser, page; + + before(async function() { + polyserve = await startServer({port:4444, root:path.join(__dirname, '../..'), moduleResolution:'node'}); + + // Create the test directory if needed. + if (!fs.existsSync(currentDir)){ + fs.mkdirSync(currentDir); + } + // And it's subdirectories. + if (!fs.existsSync(`${currentDir}/wide`)){ + fs.mkdirSync(`${currentDir}/wide`); + } + if (!fs.existsSync(`${currentDir}/narrow`)){ + fs.mkdirSync(`${currentDir}/narrow`); + } + }); + + after((done) => polyserve.close(done)); + + beforeEach(async function() { + browser = await puppeteer.launch(); + page = await browser.newPage(); + }); + + afterEach(() => browser.close()); + + describe('wide screen', function() { + beforeEach(async function() { + return page.setViewport({width: 800, height: 600}); + }); + + it('/index.html', async function() { + return takeAndCompareScreenshot(page, '', 'wide'); + }); + it('/view1', async function() { + return takeAndCompareScreenshot(page, 'view1', 'wide'); + }); + it('/view2', async function() { + return takeAndCompareScreenshot(page, 'view2', 'wide'); + }); + it('/view3', async function() { + return takeAndCompareScreenshot(page, 'view3', 'wide'); + }); + it('/404', async function() { + return takeAndCompareScreenshot(page, 'batmanNotAView', 'wide'); + }); + }); + + describe('narrow screen', function() { + beforeEach(async function() { + return page.setViewport({width: 375, height: 667}); + }); + + it('/index.html', async function() { + return takeAndCompareScreenshot(page, '', 'narrow'); + }); + it('/view1', async function() { + return takeAndCompareScreenshot(page, 'view1', 'narrow'); + }); + it('/view2', async function() { + return takeAndCompareScreenshot(page, 'view2', 'narrow'); + }); + it('/view3', async function() { + return takeAndCompareScreenshot(page, 'view3', 'narrow'); + }); + it('/404', async function() { + return takeAndCompareScreenshot(page, 'batmanNotAView', 'narrow'); + }); + }); +}); + +async function takeAndCompareScreenshot(page, route, filePrefix) { + // If you didn't specify a file, use the name of the route. + let fileName = filePrefix + '/' + (route ? route : 'index'); + + await page.goto(`http://127.0.0.1:4444/${route}`); + await page.screenshot({path: `${currentDir}/${fileName}.png`}); + return compareScreenshots(fileName); +} + +function compareScreenshots(view) { + return new Promise((resolve, reject) => { + // Note: for debugging, you can dump the screenshotted img as base64. + // fs.createReadStream(`${currentDir}/${view}.png`, { encoding: 'base64' }) + // .on('data', function (data) { + // console.log('got data', data) + // }) + // .on('end', function () { + // console.log('\n\n') + // }); + const img1 = fs.createReadStream(`${currentDir}/${view}.png`).pipe(new PNG()).on('parsed', doneReading); + const img2 = fs.createReadStream(`${baselineDir}/${view}.png`).pipe(new PNG()).on('parsed', doneReading); + + let filesRead = 0; + function doneReading() { + // Wait until both files are read. + if (++filesRead < 2) return; + + // The files should be the same size. + expect(img1.width, 'image widths are the same').equal(img2.width); + expect(img1.height, 'image heights are the same').equal(img2.height); + + // Do the visual diff. + const diff = new PNG({width: img1.width, height: img1.height}); + + // Skip the bottom/rightmost row of pixels, since it seems to be + // noise on some machines :/ + const width = img1.width - 1; + const height = img1.height - 1; + + const numDiffPixels = pixelmatch(img1.data, img2.data, diff.data, + width, height, {threshold: 0.2}); + const percentDiff = numDiffPixels/(width * height)*100; + + const stats = fs.statSync(`${currentDir}/${view}.png`); + const fileSizeInBytes = stats.size; + console.log(`📸 ${view}.png => ${fileSizeInBytes} bytes, ${percentDiff}% different`); + + //diff.pack().pipe(fs.createWriteStream(`${currentDir}/${view}-diff.png`)); + expect(numDiffPixels, 'number of different pixels').equal(0); + resolve(); + } + }); +} diff --git a/test/unit/counter-element.html b/test/unit/counter-element.html new file mode 100644 index 0000000..6c59785 --- /dev/null +++ b/test/unit/counter-element.html @@ -0,0 +1,74 @@ +<!-- +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>my-view1</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script> + <script src="../../node_modules/wct-browser-legacy/browser.js"></script> + + <!-- Import the element to test --> + <script type="module" src="../../src/components/counter-element.js"></script> + </head> + <body> + <test-fixture id="basic"> + <template> + <counter-element></counter-element> + </template> + </test-fixture> + + <script type="module"> + import 'axe-core/axe.min.js'; + import {axeReport} from 'pwa-helpers/axe-report.js'; + + suite('counter-element tests', function() { + let el; + setup(function() { + el = fixture('basic'); + }); + + test('starts empty', function() { + assert.equal(el.clicks, '0'); + assert.equal(el.value, '0'); + }); + + test('clicking on plus increments', function() { + assert.equal(el.clicks, '0'); + assert.equal(el.value, '0'); + + const buttons = el.shadowRoot.querySelectorAll('button'); + buttons[0].click(); + + assert.equal(el.clicks, '1'); + assert.equal(el.value, '1'); + }); + + test('clicking on minus decrements', function() { + assert.equal(el.clicks, '0'); + assert.equal(el.value, '0'); + + const buttons = el.shadowRoot.querySelectorAll('button'); + buttons[1].click(); + + assert.equal(el.clicks, '1'); + assert.equal(el.value, '-1'); + }); + + test('a11y', function() { + return axeReport(el); + }); + }); + </script> + </body> +</html> diff --git a/test/unit/index.html b/test/unit/index.html new file mode 100644 index 0000000..e48f5c2 --- /dev/null +++ b/test/unit/index.html @@ -0,0 +1,31 @@ +<!-- +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Tests</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <script src="../../node_modules/wct-browser-legacy/browser.js"></script> + </head> + <body> + <script> + WCT.loadSuites([ + // Load 'my-view1.html' test suite, using native shadow dom + 'counter-element.html', + // Load 'my-view1.html' test suite, using shadydom + 'counter-element.html?wc-shadydom=true&wc-ce=true', + 'views-a11y.html', + 'views-a11y.html?wc-shadydom=true&wc-ce=true', + ]); + </script> + </body> +</html> diff --git a/test/unit/views-a11y.html b/test/unit/views-a11y.html new file mode 100644 index 0000000..eb2f379 --- /dev/null +++ b/test/unit/views-a11y.html @@ -0,0 +1,82 @@ +<!-- +@license +Copyright (c) 2018 The Polymer Project Authors. All rights reserved. +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt +Code distributed by Google as part of the polymer project is also +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt +--> + +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>views a11y</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <script> + // Redux assumes `process.env.NODE_ENV` exists in the ES module build. + // https://github.com/reactjs/redux/issues/2907 + window.process = { env: { NODE_ENV: 'production' } }; + </script> + + <script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script> + <script src="../../node_modules/wct-browser-legacy/browser.js"></script> + + <!-- Import the element to test --> + <script type="module" src="../../src/components/my-view1.js"></script> + <script type="module" src="../../src/components/my-view2.js"></script> + <script type="module" src="../../src/components/my-view3.js"></script> + <script type="module" src="../../src/components/my-view404.js"></script> + </head> + <body> + <test-fixture id="view1"> + <template> + <my-view1 active></my-view1> + </template> + </test-fixture> + <test-fixture id="view2"> + <template> + <my-view2 active></my-view2> + </template> + </test-fixture> + <test-fixture id="view3"> + <template> + <my-view3 active></my-view3> + </template> + </test-fixture> + <test-fixture id="view404"> + <template> + <my-view404 active></my-view404> + </template> + </test-fixture> + + <script type="module"> + import 'axe-core/axe.min.js'; + import {axeReport} from 'pwa-helpers/axe-report.js'; + + suite('views a11y tests', function() { + test('my-view1', function() { + const el = fixture('view1'); + return axeReport(el); + }); + + test('my-view2', function() { + const el = fixture('view2'); + return axeReport(el); + }); + + test('my-view3', function() { + const el = fixture('view3'); + return axeReport(el); + }); + + test('my-view404', function() { + const el = fixture('view404'); + return axeReport(el); + }); + }); + </script> + </body> +</html> |