diff --git a/.circleci/config.yml b/.circleci/config.yml index 2626ca02694ec..44f7f089f7245 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -375,6 +375,17 @@ jobs: test_path: e2e-tests/gatsby-static-image test_command: yarn test + e2e_tests_visual-regression: + <<: *e2e-executor + steps: + - e2e-test: + test_path: e2e-tests/visual-regression + test_command: yarn test + - store_artifacts: + path: e2e-tests/visual-regression/__diff_output__ + - store_test_results: + path: e2e-tests/visual-regression/cypress/results + starters_validate: executor: node steps: @@ -582,6 +593,8 @@ workflows: <<: *e2e-test-workflow - e2e_tests_gatsby-static-image: <<: *e2e-test-workflow + - e2e_tests_visual-regression: + <<: *e2e-test-workflow - e2e_tests_development_runtime: <<: *e2e-test-workflow - e2e_tests_production_runtime: diff --git a/e2e-tests/visual-regression/.gitignore b/e2e-tests/visual-regression/.gitignore new file mode 100644 index 0000000000000..1cfc02c21453a --- /dev/null +++ b/e2e-tests/visual-regression/.gitignore @@ -0,0 +1,14 @@ +# Project dependencies +.cache +node_modules +yarn-error.log + +# Build directory +/public +.DS_Store + +# Cypress output +cypress/videos/ +cypress/screenshots/ +cypress/results/ +__diff_output__ \ No newline at end of file diff --git a/e2e-tests/visual-regression/LICENSE b/e2e-tests/visual-regression/LICENSE new file mode 100644 index 0000000000000..5169a5e4135e9 --- /dev/null +++ b/e2e-tests/visual-regression/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 gatsbyjs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/e2e-tests/visual-regression/README.md b/e2e-tests/visual-regression/README.md new file mode 100644 index 0000000000000..cf0da7fc910f1 --- /dev/null +++ b/e2e-tests/visual-regression/README.md @@ -0,0 +1,23 @@ +# Visual regression tests + +This test suite uses [cypress-image-snapshot](https://github.com/jaredpalmer/cypress-image-snapshot) +to compare screenshots of pages or elements with a saved snapshot. + +To add a test, add a page to `src/pages`, then add a test to `cypress/integration`, or add to an existing spec. + +If tests fail, a comparison image will be written to `__diff_output__`. When running in CircleCI, this is uploaded to artifacts. + +## Considerations + +Remember that the test will run on Linux in CI, so avoid tests that might change between platforms. +Using default fonts is an example. In general, if you're not testing the text itself then exclude it from your tests. Rather than comparing the full page, a good idea is to compare a wrapper element. There is a component provided for this purpose for images. + +Specifying large screen sizes can also cause problems when running locally on a small screen. The image tests use a maximum of 1024x768. The device pixel density is forced to 1, so running tests will look strange on Retina screens. This is to ensure screenshots match, whichever monitor or headless CI the tests rae running on. + +## Updating snapshots + +Run `yarn cy:update-snapshots` if you need to update them. Please note that unlike Jest, this doesn't delete outdated snapshots, so if you remove a test make sure to remove its snapshots too. + +## Credits + +Test images of Cornwall by [Benjamin Elliott](https://unsplash.com/photos/lH0_kBu5iyo) and [Red Zeppelin](https://unsplash.com/photos/uJMxXtH-Qso) via Unsplash. diff --git a/e2e-tests/visual-regression/content/relative.jpg b/e2e-tests/visual-regression/content/relative.jpg new file mode 100644 index 0000000000000..8a1a95b1e4555 Binary files /dev/null and b/e2e-tests/visual-regression/content/relative.jpg differ diff --git a/e2e-tests/visual-regression/cypress.json b/e2e-tests/visual-regression/cypress.json new file mode 100644 index 0000000000000..fca52835f895a --- /dev/null +++ b/e2e-tests/visual-regression/cypress.json @@ -0,0 +1,11 @@ +{ + "baseUrl": "http://localhost:9000", + "video": false, + "reporter": "junit", + "reporterOptions": { + "mochaFile": "cypress/results/junit-[hash].xml", + "overwrite": false, + "html": false, + "json": true + } +} diff --git a/e2e-tests/visual-regression/cypress/fixtures/example.json b/e2e-tests/visual-regression/cypress/fixtures/example.json new file mode 100644 index 0000000000000..da18d9352a17d --- /dev/null +++ b/e2e-tests/visual-regression/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} \ No newline at end of file diff --git a/e2e-tests/visual-regression/cypress/integration/image.js b/e2e-tests/visual-regression/cypress/integration/image.js new file mode 100644 index 0000000000000..14d8e27b8f3f1 --- /dev/null +++ b/e2e-tests/visual-regression/cypress/integration/image.js @@ -0,0 +1,26 @@ +const testCases = [ + ["fixed image", "/images/fixed"], + ["fixed image smaller than requested size", "/images/fixed-too-big"], + ["fluid image", "/images/fluid"], + ["constrained image", "/images/constrained"], +] + +const sizes = [["iphone-6"], ["ipad-2"], [1027, 768]] + +describe(`GatsbyImage`, () => { + sizes.forEach(size => { + testCases.forEach(([title, path]) => { + describe(`${title}`, () => { + it(`renders correctly on ${size.join("x")}`, () => { + cy.viewport(...size) + cy.visit(path) + // Wait for main image to load + cy.get("[data-main-image]").should("have.css", "opacity", "1") + // Wait for blur-up + cy.wait(1000) + cy.get("#test-wrapper").matchImageSnapshot() + }) + }) + }) + }) +}) diff --git a/e2e-tests/visual-regression/cypress/plugins/index.js b/e2e-tests/visual-regression/cypress/plugins/index.js new file mode 100644 index 0000000000000..3ecbcd1f8e3c0 --- /dev/null +++ b/e2e-tests/visual-regression/cypress/plugins/index.js @@ -0,0 +1,24 @@ +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) +const { addMatchImageSnapshotPlugin } = require("cypress-image-snapshot/plugin") + +module.exports = (on, config) => { + addMatchImageSnapshotPlugin(on, config) + on("before:browser:launch", (browser = {}, launchOptions) => { + if (browser.family === "chromium" || browser.family === "chrome") { + // Make retina screens run at 1x density so they match the versions in CI + launchOptions.push("--force-device-scale-factor=1") + } + return launchOptions + }) +} diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on 1027x768.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on 1027x768.snap.png new file mode 100644 index 0000000000000..9d473abd64996 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on 1027x768.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on ipad-2.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on ipad-2.snap.png new file mode 100644 index 0000000000000..8e6a120839fd3 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on ipad-2.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on iphone-6.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on iphone-6.snap.png new file mode 100644 index 0000000000000..a9c6c0c0e0247 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- constrained image -- renders correctly on iphone-6.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on 1027x768.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on 1027x768.snap.png new file mode 100644 index 0000000000000..59f2f3f231a83 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on 1027x768.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on ipad-2.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on ipad-2.snap.png new file mode 100644 index 0000000000000..59f2f3f231a83 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on ipad-2.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on iphone-6.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on iphone-6.snap.png new file mode 100644 index 0000000000000..59f2f3f231a83 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image -- renders correctly on iphone-6.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on 1027x768.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on 1027x768.snap.png new file mode 100644 index 0000000000000..1e3afed9093bc Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on 1027x768.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on ipad-2.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on ipad-2.snap.png new file mode 100644 index 0000000000000..1e3afed9093bc Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on ipad-2.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on iphone-6.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on iphone-6.snap.png new file mode 100644 index 0000000000000..d01b074d2d8e3 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fixed image smaller than requested size -- renders correctly on iphone-6.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on 1027x768.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on 1027x768.snap.png new file mode 100644 index 0000000000000..80a23ad284113 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on 1027x768.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on ipad-2.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on ipad-2.snap.png new file mode 100644 index 0000000000000..dc4abee90228e Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on ipad-2.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on iphone-6.snap.png b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on iphone-6.snap.png new file mode 100644 index 0000000000000..141e13fdc3608 Binary files /dev/null and b/e2e-tests/visual-regression/cypress/snapshots/image.js/GatsbyImage -- fluid image -- renders correctly on iphone-6.snap.png differ diff --git a/e2e-tests/visual-regression/cypress/support/index.js b/e2e-tests/visual-regression/cypress/support/index.js new file mode 100644 index 0000000000000..e36217f8d8f7b --- /dev/null +++ b/e2e-tests/visual-regression/cypress/support/index.js @@ -0,0 +1,26 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +import "gatsby-cypress" +import { addMatchImageSnapshotCommand } from "cypress-image-snapshot/command" + +addMatchImageSnapshotCommand({ + customDiffDir: `/__diff_output__`, + customDiffConfig: { + threshold: 0.1 + }, + failureThreshold: 0.03, + failureThresholdType: `percent` +}) diff --git a/e2e-tests/visual-regression/gatsby-config.js b/e2e-tests/visual-regression/gatsby-config.js new file mode 100644 index 0000000000000..fb1600ca4322e --- /dev/null +++ b/e2e-tests/visual-regression/gatsby-config.js @@ -0,0 +1,19 @@ +const path = require(`path`) + +module.exports = { + siteMetadata: { + title: `Gatsby Visual tests`, + }, + plugins: [ + { + resolve: `gatsby-source-filesystem`, + options: { + name: `img`, + path: `${__dirname}/src/images/`, + }, + }, + `gatsby-plugin-image`, + `gatsby-plugin-sharp`, + `gatsby-transformer-sharp`, + ], +} diff --git a/e2e-tests/visual-regression/package.json b/e2e-tests/visual-regression/package.json new file mode 100644 index 0000000000000..e5f094e56a307 --- /dev/null +++ b/e2e-tests/visual-regression/package.json @@ -0,0 +1,45 @@ +{ + "name": "gatsby-starter-default", + "description": "Gatsby default starter", + "version": "1.0.0", + "author": "Kyle Mathews ", + "dependencies": { + "cypress": "^3.1.0", + "cypress-image-snapshot": "^3.1.1", + "gatsby": "^2.0.118", + "gatsby-plugin-image": "^0.0.2", + "gatsby-plugin-sharp": "^2.0.20", + "gatsby-source-filesystem": "^2.3.35", + "gatsby-transformer-sharp": "^2.5.19", + "react": "^16.8.0", + "react-dom": "^16.8.0" + }, + "keywords": [ + "gatsby" + ], + "license": "MIT", + "scripts": { + "build": "gatsby build", + "develop": "gatsby develop", + "format": "prettier --write '**/*.js'", + "test": "cross-env CYPRESS_SUPPORT=y npm run build && npm run start-server-and-test", + "start-server-and-test": "start-server-and-test serve http://localhost:9000 cy:run", + "serve": "gatsby serve", + "cy:open": "cypress open", + "cy:run": "cypress run --browser chrome", + "cy:update-snapshots": "cypress run --browser chrome --env updateSnapshots=true", + "cy:clean-snapshots": "rimraf cypress/snapshots/*" + }, + "devDependencies": { + "cross-env": "^5.2.0", + "cypress-junit-reporter": "^1.3.1", + "gatsby-cypress": "0.4.11", + "is-ci": "^2.0.0", + "prettier": "2.0.4", + "start-server-and-test": "^1.7.1" + }, + "repository": { + "type": "git", + "url": "https://github.com/gatsbyjs/gatsby-starter-default" + } +} diff --git a/e2e-tests/visual-regression/src/components/header.js b/e2e-tests/visual-regression/src/components/header.js new file mode 100644 index 0000000000000..aaad59fe864a8 --- /dev/null +++ b/e2e-tests/visual-regression/src/components/header.js @@ -0,0 +1,38 @@ +import * as React from "react" +import { Link } from "gatsby" +import PropTypes from "prop-types" + +const Header = ({ siteTitle }) => ( +
+
+

+ + {siteTitle} + +

+
+
+) + +Header.propTypes = { + siteTitle: PropTypes.string.isRequired, +} + +export default Header diff --git a/e2e-tests/visual-regression/src/components/layout.css b/e2e-tests/visual-regression/src/components/layout.css new file mode 100644 index 0000000000000..169256bd5dda6 --- /dev/null +++ b/e2e-tests/visual-regression/src/components/layout.css @@ -0,0 +1,612 @@ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +progress { + vertical-align: baseline; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} +a:active, +a:hover { + outline-width: 0; +} +abbr[title] { + border-bottom: none; + text-decoration: underline; + text-decoration: underline dotted; +} +b, +strong { + font-weight: inherit; + font-weight: bolder; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background-color: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} + +svg:not(:root) { + overflow: hidden; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +figure { + margin: 1em 40px; +} +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} +button, +input, +optgroup, +select, +textarea { + font: inherit; + margin: 0; +} +optgroup { + font-weight: 700; +} +button, +input { + overflow: visible; +} +button, +select { + text-transform: none; +} +[type="reset"], +[type="submit"], +button, +html [type="button"] { + -webkit-appearance: button; +} +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner, +button::-moz-focus-inner { + border-style: none; + padding: 0; +} +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring, +button:-moz-focusring { + outline: 1px dotted ButtonText; +} +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} +textarea { + overflow: auto; +} +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; +} +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} +html { + font: 112.5%/1.45em georgia, serif; + box-sizing: border-box; + overflow-y: scroll; +} +* { + box-sizing: inherit; +} +*:before { + box-sizing: inherit; +} +*:after { + box-sizing: inherit; +} +body { + color: hsla(0, 0%, 0%, 0.8); + font-family: georgia, serif; + font-weight: normal; + word-wrap: break-word; + font-kerning: normal; + -moz-font-feature-settings: "kern", "liga", "clig", "calt"; + -ms-font-feature-settings: "kern", "liga", "clig", "calt"; + -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; + font-feature-settings: "kern", "liga", "clig", "calt"; +} + +h1 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 2.25rem; + line-height: 1.1; +} +h2 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1.62671rem; + line-height: 1.1; +} +h3 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1.38316rem; + line-height: 1.1; +} +h4 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1rem; + line-height: 1.1; +} +h5 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 0.85028rem; + line-height: 1.1; +} +h6 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 0.78405rem; + line-height: 1.1; +} +hgroup { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +ul { + margin-left: 1.45rem; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + list-style-position: outside; + list-style-image: none; +} +ol { + margin-left: 1.45rem; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + list-style-position: outside; + list-style-image: none; +} +dl { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +dd { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +p { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +figure { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +pre { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + font-size: 0.85rem; + line-height: 1.42; + background: hsla(0, 0%, 0%, 0.04); + border-radius: 3px; + overflow: auto; + word-wrap: normal; + padding: 1.45rem; +} +table { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + font-size: 1rem; + line-height: 1.45rem; + border-collapse: collapse; + width: 100%; +} +fieldset { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +blockquote { + margin-left: 1.45rem; + margin-right: 1.45rem; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +form { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +noscript { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +iframe { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +hr { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: calc(1.45rem - 1px); + background: hsla(0, 0%, 0%, 0.2); + border: none; + height: 1px; +} +address { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; +} +b { + font-weight: bold; +} +strong { + font-weight: bold; +} +dt { + font-weight: bold; +} +th { + font-weight: bold; +} +li { + margin-bottom: calc(1.45rem / 2); +} +ol li { + padding-left: 0; +} +ul li { + padding-left: 0; +} +li > ol { + margin-left: 1.45rem; + margin-bottom: calc(1.45rem / 2); + margin-top: calc(1.45rem / 2); +} +li > ul { + margin-left: 1.45rem; + margin-bottom: calc(1.45rem / 2); + margin-top: calc(1.45rem / 2); +} +blockquote *:last-child { + margin-bottom: 0; +} +li *:last-child { + margin-bottom: 0; +} +p *:last-child { + margin-bottom: 0; +} +li > p { + margin-bottom: calc(1.45rem / 2); +} +code { + font-size: 0.85rem; + line-height: 1.45rem; +} +kbd { + font-size: 0.85rem; + line-height: 1.45rem; +} +samp { + font-size: 0.85rem; + line-height: 1.45rem; +} +abbr { + border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); + cursor: help; +} +acronym { + border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); + cursor: help; +} +abbr[title] { + border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); + cursor: help; + text-decoration: none; +} +thead { + text-align: left; +} +td, +th { + text-align: left; + border-bottom: 1px solid hsla(0, 0%, 0%, 0.12); + font-feature-settings: "tnum"; + -moz-font-feature-settings: "tnum"; + -ms-font-feature-settings: "tnum"; + -webkit-font-feature-settings: "tnum"; + padding-left: 0.96667rem; + padding-right: 0.96667rem; + padding-top: 0.725rem; + padding-bottom: calc(0.725rem - 1px); +} +th:first-child, +td:first-child { + padding-left: 0; +} +th:last-child, +td:last-child { + padding-right: 0; +} +tt, +code { + background-color: hsla(0, 0%, 0%, 0.04); + border-radius: 3px; + font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", + "Liberation Mono", Menlo, Courier, monospace; + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; +} +pre code { + background: none; + line-height: 1.42; +} +code:before, +code:after, +tt:before, +tt:after { + letter-spacing: -0.2em; + content: " "; +} +pre code:before, +pre code:after, +pre tt:before, +pre tt:after { + content: ""; +} +@media only screen and (max-width: 480px) { + html { + font-size: 100%; + } +} diff --git a/e2e-tests/visual-regression/src/components/layout.js b/e2e-tests/visual-regression/src/components/layout.js new file mode 100644 index 0000000000000..c111a6aabf014 --- /dev/null +++ b/e2e-tests/visual-regression/src/components/layout.js @@ -0,0 +1,35 @@ +import * as React from "react" +import { StaticQuery, graphql } from "gatsby" + +import Header from "./header" +import "./layout.css" + +const Layout = ({ children }) => ( + ( + +
+
+ {children} +
+ + )} + /> +) + +export default Layout diff --git a/e2e-tests/visual-regression/src/components/test-wrapper.js b/e2e-tests/visual-regression/src/components/test-wrapper.js new file mode 100644 index 0000000000000..0c854f3f3a718 --- /dev/null +++ b/e2e-tests/visual-regression/src/components/test-wrapper.js @@ -0,0 +1,16 @@ +import React from "react" +export function TestWrapper({ children, style }) { + return ( +
+ {children} +
+ ) +} diff --git a/e2e-tests/visual-regression/src/images/cornwall.jpg b/e2e-tests/visual-regression/src/images/cornwall.jpg new file mode 100644 index 0000000000000..e35192f9c18cc Binary files /dev/null and b/e2e-tests/visual-regression/src/images/cornwall.jpg differ diff --git a/e2e-tests/visual-regression/src/images/gatsby-icon.png b/e2e-tests/visual-regression/src/images/gatsby-icon.png new file mode 100644 index 0000000000000..908bc78a7f559 Binary files /dev/null and b/e2e-tests/visual-regression/src/images/gatsby-icon.png differ diff --git a/e2e-tests/visual-regression/src/images/landsend.jpg b/e2e-tests/visual-regression/src/images/landsend.jpg new file mode 100644 index 0000000000000..df1af8c817358 Binary files /dev/null and b/e2e-tests/visual-regression/src/images/landsend.jpg differ diff --git a/e2e-tests/visual-regression/src/pages/404.js b/e2e-tests/visual-regression/src/pages/404.js new file mode 100644 index 0000000000000..99945d437e60a --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/404.js @@ -0,0 +1,11 @@ +import * as React from "react" +import Layout from "../components/layout" + +const NotFoundPage = () => ( + +

NOT FOUND

+

You just hit a route that doesn't exist... the sadness.

+
+) + +export default NotFoundPage diff --git a/e2e-tests/visual-regression/src/pages/images/constrained.js b/e2e-tests/visual-regression/src/pages/images/constrained.js new file mode 100644 index 0000000000000..0118fe6e1da40 --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/images/constrained.js @@ -0,0 +1,34 @@ +import * as React from "react" +import { GatsbyImage, getImage } from "gatsby-plugin-image" +import { useStaticQuery, graphql } from "gatsby" +import { TestWrapper } from "../../components/test-wrapper" +import Layout from "../../components/layout" + +const Page = () => { + const data = useStaticQuery(graphql` + query { + file(relativePath: { eq: "cornwall.jpg" }) { + childImageSharp { + gatsbyImage(maxWidth: 1024, layout: CONSTRAINED) { + imageData + } + } + } + } + `) + + return ( + +

Constrained

+ + + +
+ ) +} + +export default Page diff --git a/e2e-tests/visual-regression/src/pages/images/fixed-too-big.js b/e2e-tests/visual-regression/src/pages/images/fixed-too-big.js new file mode 100644 index 0000000000000..8138cc450098c --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/images/fixed-too-big.js @@ -0,0 +1,35 @@ +import * as React from "react" +import { GatsbyImage, getImage } from "gatsby-plugin-image" +import { useStaticQuery, graphql } from "gatsby" +import { TestWrapper } from "../../components/test-wrapper" +import Layout from "../../components/layout" + +const Page = () => { + const data = useStaticQuery(graphql` + query { + file(relativePath: { eq: "landsend.jpg" }) { + childImageSharp { + gatsbyImage(width: 500, height: 500, layout: FIXED) { + imageData + } + } + } + } + `) + console.log(data) + + return ( + +

Fixed larger than source image

+ + + +
+ ) +} + +export default Page diff --git a/e2e-tests/visual-regression/src/pages/images/fixed.js b/e2e-tests/visual-regression/src/pages/images/fixed.js new file mode 100644 index 0000000000000..01d33161d2b41 --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/images/fixed.js @@ -0,0 +1,34 @@ +import * as React from "react" +import { GatsbyImage, getImage } from "gatsby-plugin-image" +import { useStaticQuery, graphql } from "gatsby" +import { TestWrapper } from "../../components/test-wrapper" +import Layout from "../../components/layout" + +const Page = () => { + const data = useStaticQuery(graphql` + query { + file(relativePath: { eq: "cornwall.jpg" }) { + childImageSharp { + gatsbyImage(width: 240, height: 100, layout: FIXED) { + imageData + } + } + } + } + `) + + return ( + +

Fixed width and height

+ + + +
+ ) +} + +export default Page diff --git a/e2e-tests/visual-regression/src/pages/images/fluid.js b/e2e-tests/visual-regression/src/pages/images/fluid.js new file mode 100644 index 0000000000000..77ea021821a25 --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/images/fluid.js @@ -0,0 +1,34 @@ +import * as React from "react" +import { GatsbyImage, getImage } from "gatsby-plugin-image" +import { useStaticQuery, graphql } from "gatsby" +import { TestWrapper } from "../../components/test-wrapper" +import Layout from "../../components/layout" + +const Page = () => { + const data = useStaticQuery(graphql` + query { + file(relativePath: { eq: "cornwall.jpg" }) { + childImageSharp { + gatsbyImage(maxWidth: 1024, layout: FLUID) { + imageData + } + } + } + } + `) + + return ( + +

Fluid, maxWidth

+ + + +
+ ) +} + +export default Page diff --git a/e2e-tests/visual-regression/src/pages/index.js b/e2e-tests/visual-regression/src/pages/index.js new file mode 100644 index 0000000000000..e7c2bd972d7d4 --- /dev/null +++ b/e2e-tests/visual-regression/src/pages/index.js @@ -0,0 +1,18 @@ +import * as React from "react" +import { Link } from "gatsby" + +import Layout from "../components/layout" + +const IndexPage = () => ( + +

Gatsby Image integration test

+
    +
  • /images/fixed
  • +
  • /images/fixed-too-big
  • +
  • /images/fluid
  • +
  • /images/constrained
  • +
+
+) + +export default IndexPage