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

UI tests for Gatsbygram #4790

Merged
merged 9 commits into from
Apr 14, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ jobs:
script:
- yarn test

- stage: gatsbygram ui tests
language: node_js
Copy link
Contributor

Choose a reason for hiding this comment

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

@tsriram Can you add the env var here (maybe you tried that already)? Travis might not pick it up until this branch is merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@m-allanson Ah, didn't know that ENV variables are not accessible before merging. Nope, I didn't try adding the variable here. Adding it here will make it public right? I'm not sure if it's okay. From Cypress docs:

If you have a public project you should still keep your record key secret. If someone knows both your record key and your projectId, they could record test runs for your project - which would mix up all of your results!

Wonder if it's okay for us to make it public? If yes, we can just pass the key from the npm script itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, didn't know that ENV variables are not accessible before merging.

Oh hrmm, it seems I was wrong about that, Travis will use the yaml file from the current branch: https://docs.travis-ci.com/user/customizing-the-build/#Building-Specific-Branches

Yeah adding it here will make it public, but you can use the Travis CLI to encrypt env vars. See an example here.

Although pay attention to their note:

Encryption and decryption keys are tied to the repository. If you fork a project and add it to Travis CI, it will not have access to the encrypted variables.

Otherwise you may spend a lot of time (like I did 😅) wondering why your env var isn't working. It may be easier to merge this branch as-is, and then create smaller PRs straight from this repo to tinker with the travis.yml config.

Alternatively @KyleAMathews could add the env var via the Travis site (as you mentioned originally) which would certainly be quicker :), but I think it's nicer to keep the Travis config under version control where possible.

Copy link
Contributor Author

@tsriram tsriram Apr 5, 2018

Choose a reason for hiding this comment

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

Oh hrmm, it seems I was wrong about that, Travis will use the yaml file from the current branch

Probably not 😄 Looks like the environment variables defined in repository settings are not "automatically" available to forks: https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings. I think even if @KyleAMathews adds the env variable, it's not going to work. So, as you said it's probably better to merge this and have a branch from this repo itself to get this working.

node_js:
- '6'
- '8'
cache:
yarn: true
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
- cd examples/gatsbygram
install:
- yarn
script:
- yarn test


- stage: www graphql docker image build and push
if: (NOT type = pull_request) AND branch = master
env:
Expand Down
1 change: 1 addition & 0 deletions examples/gatsbygram/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
public
.cache
node_modules
cypress/videos/
5 changes: 5 additions & 0 deletions examples/gatsbygram/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"baseUrl": "http://localhost:8000",
"fixturesFolder": "data",
"projectId": "c9d3r3"
}
28 changes: 28 additions & 0 deletions examples/gatsbygram/cypress/integration/about_page_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
describe(`About Page`, () => {
it(`successfully loads`, () => {
cy.visit(`/about`)
})

it(`contains the title with an SVG icon and text "Gatsbygram"`, () => {
cy.getTestElement(`site-title`).get(`svg`)
cy.getTestElement(`site-title`).contains(`Gatsbygram`)
})

it(`clicking on site title takes to home page`, () => {
cy.getTestElement(`site-title`).click()
cy.url().should(`eq`, `${Cypress.config(`baseUrl`)}/`)

// go back to about page for further testing
cy.visit(`/about`)
})

it(`contains a link to about page in nav bar and it works`, () => {
cy.getTestElement(`about-link`).contains(`About`)
cy.getTestElement(`about-link`).click()
cy.url().should(`eq`, `${Cypress.config(`baseUrl`)}/about/`)
})

it(`displays title of the page`, () => {
cy.getTestElement(`about-title`).contains(`About Gatsbygram`)
})
})
106 changes: 106 additions & 0 deletions examples/gatsbygram/cypress/integration/home_page_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

describe(`The Home Page`, () => {
it(`successfully loads`, () => {
cy.visit(`/`)
})

it(`contains the title with an SVG icon and text "Gatsbygram"`, () => {
cy.getTestElement(`site-title`).get(`svg`)
cy.getTestElement(`site-title`).contains(`Gatsbygram`)
})

it(`contains a link to about page in nav bar and it works`, () => {
cy.getTestElement(`about-link`).contains(`About`)
cy.getTestElement(`about-link`).click()
cy.url().should(`eq`, `${Cypress.config(`baseUrl`)}/about/`)
// go back to home page
cy.visit(`/`)
})

it(`renders user avatar and name`, () => {
cy.getTestElement(`user-avatar`).get(`img`)
cy.getTestElement(`username`).contains(`kyle__mathews`)
})

it(`shows user's posts and followers count`, () => {
cy.getTestElement(`user-meta`).contains(`100 posts`)
cy.getTestElement(`user-meta`).contains(`192k followers`)
})

it(`shows number of likes when hovered on a post`, () => {
cy.fixture(`posts`).then((postsData) => {
const post = postsData[0]
cy.getTestElement(`post`).first().trigger(`mouseover`)
cy.getTestElement(`likes`).contains(post.likes)
cy.getTestElement(`post`).first().trigger(`mouseout`)
})
})

it(`opens and closes a post`, () => {
cy.fixture(`posts`).then((postsData) => {
const post = postsData[0]
cy.getTestElement(`post`).first().click()
cy.url().should('contain', post.id)
cy.getTestElement(`post-detail-avatar`).should(`have.attr`, `src`, post.avatar)
cy.getTestElement(`post-detail-username`).contains(post.username)
cy.getTestElement(`post-detail-likes`).contains(post.likes)
cy.getTestElement(`post-detail-text`).contains(post.username)
cy.getTestElement(`post-detail-text`).contains(post.text)
cy.getTestElement(`modal-close`).click()
cy.url().should(`eq`, `${Cypress.config(`baseUrl`)}/`)
})
})

it(`goes to next / previous post on clicking arrow icons`, () => {
cy.fixture(`posts`).then((postsData) => {
const post1 = postsData[0]
const post2 = postsData[1]
// open fist post
cy.getTestElement(`post`).first().click()
cy.url().should('contain', post1.id)
// click right arrow icon to go to 2nd post
cy.getTestElement(`next-post`).click()
cy.url().should('contain', post2.id)
// press left arrow to go back to 1st post
cy.getTestElement(`previous-post`).click()
cy.url().should('contain', post1.id)
// close the post
cy.getTestElement(`modal-close`).click()
})
})

it(`goes to next / previous post with keyboard shortcut`, () => {
cy.fixture(`posts`).then((postsData) => {
const post1 = postsData[0]
const post2 = postsData[1]
// open fist post
cy.getTestElement(`post`).first().click()
cy.url().should('contain', post1.id)
// press right arrow to go to 2nd post
cy.get(`body`).type(`{rightarrow}`)
cy.url().should('contain', post2.id)
// press left arrow to go back to 1st post
cy.get(`body`).type(`{leftarrow}`)
cy.url().should('contain', post1.id)
// close the post
cy.getTestElement(`modal-close`).click()
})
})

it(`loads more posts when Load More button is clicked & on scroll`, () => {
// initially loads 12 posts
cy.getTestElement(`post`).should('have.length', 12)

// loads 12 more posts when Load More button is clicked
cy.getTestElement(`load-more`).click()
cy.getTestElement(`post`).should('have.length', 24)

// loads 12 more posts when scrolled to bottom
// cy.getTestElement(`home-container`).scrollTo(`0%`, `99%`)
cy.window().scrollTo(`bottom`)
cy.getTestElement(`post`).should('have.length', 36)

// let's go back to top
cy.window().scrollTo(`top`)
})
})
30 changes: 30 additions & 0 deletions examples/gatsbygram/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

// copied from here - https://github.com/cypress-io/cypress/issues/1212#issuecomment-360395261
Cypress.Commands.add("getTestElement", (selector) => {
return cy.get(`[data-testid="${selector}"]`)
})
20 changes: 20 additions & 0 deletions examples/gatsbygram/cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// 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 commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
32 changes: 19 additions & 13 deletions examples/gatsbygram/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"version": "1.0.0",
"author": "Kyle Mathews <mathews.kyle@gmail.com>",
"dependencies": {
"gatsby": "^1.9.52",
"gatsby-image": "^1.0.39",
"gatsby-link": "^1.6.20",
"gatsby-plugin-glamor": "^1.6.8",
"gatsby-plugin-google-analytics": "^1.0.8",
"gatsby-plugin-manifest": "^1.0.8",
"gatsby-plugin-offline": "^1.0.9",
"gatsby-plugin-sharp": "^1.6.8",
"gatsby-source-filesystem": "^1.5.2",
"gatsby-transformer-json": "^1.0.8",
"gatsby-transformer-sharp": "^1.6.8",
"gatsby": "latest",
"gatsby-image": "latest",
"gatsby-link": "latest",
"gatsby-plugin-glamor": "latest",
"gatsby-plugin-google-analytics": "latest",
"gatsby-plugin-manifest": "latest",
"gatsby-plugin-offline": "latest",
"gatsby-plugin-sharp": "latest",
"gatsby-source-filesystem": "latest",
"gatsby-transformer-json": "latest",
"gatsby-transformer-sharp": "latest",
"instagram-screen-scrape": "^2.0.0",
"lodash": "^4.16.4",
"mkdirp": "^0.5.1",
Expand All @@ -38,10 +38,16 @@
"main": "n/a",
"scripts": {
"lint": "./node_modules/.bin/eslint --ext .js,.jsx --ignore-pattern public .",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "start-server-and-test develop http://localhost:8000 cy:run",
"develop": "gatsby develop",
"dev": "gatsby develop",
"build": "gatsby build",
"deploy": "gatsby build --prefix-paths && gh-pages -d public"
"deploy": "gatsby build --prefix-paths && gh-pages -d public",
"cy:open": "cypress open",
"cy:run": "cypress run"
},
"devDependencies": {
"cypress": "^2.1.0",
"start-server-and-test": "^1.1.4"
}
}
3 changes: 3 additions & 0 deletions examples/gatsbygram/src/components/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class GatsbyGramModal extends React.Component {
}}
>
<CaretLeft
data-testid="previous-post"
css={{
cursor: `pointer`,
fontSize: `50px`,
Expand All @@ -135,6 +136,7 @@ class GatsbyGramModal extends React.Component {
location: { pathname: this.props.location.pathname },
})}
<CaretRight
data-testid="next-post"
css={{
cursor: `pointer`,
fontSize: `50px`,
Expand All @@ -145,6 +147,7 @@ class GatsbyGramModal extends React.Component {
/>
</div>
<Close
data-testid="modal-close"
onClick={() => navigateTo(`/`)}
css={{
cursor: `pointer`,
Expand Down
5 changes: 4 additions & 1 deletion examples/gatsbygram/src/components/post-detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PostDetail extends React.Component {
}}
>
<img
data-testid="post-detail-avatar"
src={avatar}
alt={username}
css={{
Expand All @@ -42,6 +43,7 @@ class PostDetail extends React.Component {
}}
/>
<h5
data-testid="post-detail-username"
css={{
lineHeight: rhythm(1),
marginBottom: rhythm(3 / 4),
Expand All @@ -66,6 +68,7 @@ class PostDetail extends React.Component {
}}
>
<strong
data-testid="post-detail-likes"
css={{
float: `left`,
}}
Expand All @@ -81,7 +84,7 @@ class PostDetail extends React.Component {
{weeksAgo}w
</strong>
</div>
<div>
<div data-testid="post-detail-text">
<strong>{username}</strong> {text}
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions examples/gatsbygram/src/components/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Post extends React.Component {
const { small } = smallImage.childImageSharp
return (
<Link
data-testid="post"
to={`/${id}/`}
onTouchStart={() => (touched = true)}
onMouseEnter={() => {
Expand Down Expand Up @@ -93,6 +94,7 @@ class Post extends React.Component {
{/* overlay */}
{this.state.hovering && (
<div
data-testid="likes"
css={{
position: `absolute`,
top: 0,
Expand Down
2 changes: 2 additions & 0 deletions examples/gatsbygram/src/layouts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class DefaultLayout extends React.Component {
}}
>
<h1
data-testid="site-title"
css={{
...scale(4 / 5),
lineHeight: 1,
Expand Down Expand Up @@ -131,6 +132,7 @@ class DefaultLayout extends React.Component {
</h1>
</Link>
<Link
data-testid="about-link"
to="/about/"
css={{
color: `inherit`,
Expand Down
2 changes: 1 addition & 1 deletion examples/gatsbygram/src/pages/about.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class About extends React.Component {
padding: rhythm(3 / 4),
}}
>
<h1>About Gatsbygram</h1>
<h1 data-testid="about-title">About Gatsbygram</h1>
<p>
Gatsbygram is an example website built with the JavaScript web
framework
Expand Down
Loading