first commit
This commit is contained in:
6
ui/tests/e2e/.eslintrc.js
Normal file
6
ui/tests/e2e/.eslintrc.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: ['cypress'],
|
||||
env: {
|
||||
'cypress/globals': true,
|
||||
},
|
||||
}
|
||||
55
ui/tests/e2e/plugins/index.js
Normal file
55
ui/tests/e2e/plugins/index.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// https://docs.cypress.io/guides/guides/plugins-guide.html
|
||||
module.exports = (on, config) => {
|
||||
// Dynamic configuration
|
||||
// https://docs.cypress.io/guides/references/configuration.html
|
||||
return Object.assign({}, config, {
|
||||
// ===
|
||||
// General
|
||||
// https://docs.cypress.io/guides/references/configuration.html#Global
|
||||
// ===
|
||||
watchForFileChanges: true,
|
||||
// ===
|
||||
// Environment variables
|
||||
// https://docs.cypress.io/guides/guides/environment-variables.html#Option-1-cypress-json
|
||||
// ===
|
||||
env: {
|
||||
CI: process.env.CI,
|
||||
},
|
||||
// ===
|
||||
// Viewport
|
||||
// https://docs.cypress.io/guides/references/configuration.html#Viewport
|
||||
// ===
|
||||
viewportWidth: 1280,
|
||||
viewportHeight: 720,
|
||||
// ===
|
||||
// Animations
|
||||
// https://docs.cypress.io/guides/references/configuration.html#Animations
|
||||
// ===
|
||||
waitForAnimations: true,
|
||||
animationDistanceThreshold: 4,
|
||||
// ===
|
||||
// Timeouts
|
||||
// https://docs.cypress.io/guides/references/configuration.html#Timeouts
|
||||
// ===
|
||||
defaultCommandTimeout: 4000,
|
||||
execTimeout: 60000,
|
||||
pageLoadTimeout: 60000,
|
||||
requestTimeout: 5000,
|
||||
responseTimeout: 30000,
|
||||
// ===
|
||||
// Main Directories
|
||||
// https://docs.cypress.io/guides/references/configuration.html#Folders-Files
|
||||
// ===
|
||||
supportFile: 'tests/e2e/support/setup.js',
|
||||
integrationFolder: 'tests/e2e/specs',
|
||||
fixturesFolder: 'tests/e2e/fixtures',
|
||||
// ===
|
||||
// Videos & Screenshots
|
||||
// https://docs.cypress.io/guides/core-concepts/screenshots-and-videos.html
|
||||
// ===
|
||||
videoUploadOnPasses: true,
|
||||
videoCompression: 32,
|
||||
videosFolder: 'tests/e2e/videos',
|
||||
screenshotsFolder: 'tests/e2e/screenshots',
|
||||
})
|
||||
}
|
||||
82
ui/tests/e2e/specs/auth.e2e.js
Normal file
82
ui/tests/e2e/specs/auth.e2e.js
Normal file
@@ -0,0 +1,82 @@
|
||||
describe('Authentication', () => {
|
||||
it('login link exists on the home page when logged out', () => {
|
||||
cy.visit('/')
|
||||
cy.contains('a', 'Log in').should('have.attr', 'href', '/login')
|
||||
})
|
||||
|
||||
it('login form shows an error on failure', () => {
|
||||
cy.visit('/login')
|
||||
|
||||
// Enter bad login info
|
||||
cy.get('input[name="username"]').type('badUsername')
|
||||
cy.get('input[name="password"]').type('badPassword')
|
||||
|
||||
// Submit the login form
|
||||
cy.contains('button', 'Log in').click()
|
||||
|
||||
// Ensure that an error displays
|
||||
cy.contains('error logging in')
|
||||
})
|
||||
|
||||
it('successful login works redirects to the home page and logging out works', () => {
|
||||
cy.visit('/login')
|
||||
|
||||
// Enter the user-supplied username and password
|
||||
cy.get('input[name="username"]').type('admin')
|
||||
cy.get('input[name="password"]').type('password')
|
||||
|
||||
// Submit the login form
|
||||
cy.contains('button', 'Log in').click()
|
||||
|
||||
// Confirm redirection to the homepage
|
||||
cy.location('pathname').should('equal', '/')
|
||||
|
||||
// Confirm a logout link exists
|
||||
cy.contains('a', 'Log out')
|
||||
})
|
||||
|
||||
it('login after attempting to visit authenticated route redirects to that route after login', () => {
|
||||
cy.visit('/profile?someQuery')
|
||||
|
||||
// Confirm redirection to the login page
|
||||
cy.location('pathname').should('equal', '/login')
|
||||
|
||||
// Enter the user-supplied username and password
|
||||
cy.get('input[name="username"]').type('admin')
|
||||
cy.get('input[name="password"]').type('password')
|
||||
|
||||
// Submit the login form
|
||||
cy.contains('button', 'Log in').click()
|
||||
|
||||
// Confirm redirection to the homepage
|
||||
cy.location('pathname').should('equal', '/profile')
|
||||
cy.location('search').should('equal', '?someQuery')
|
||||
|
||||
// Confirm a logout link exists
|
||||
cy.contains('a', 'Log out')
|
||||
})
|
||||
|
||||
it('logout link logs the user out when logged in', () => {
|
||||
cy.logIn()
|
||||
|
||||
// Click the logout link
|
||||
cy.contains('a', 'Log out').click()
|
||||
|
||||
// Confirm that the user is logged out
|
||||
cy.contains('a', 'Log in')
|
||||
})
|
||||
|
||||
it('logout from an authenticated route redirects to home', () => {
|
||||
cy.logIn()
|
||||
cy.visit('/profile')
|
||||
|
||||
// Click the logout link
|
||||
cy.contains('a', 'Log out').click()
|
||||
|
||||
// Confirm we're on the correct page
|
||||
cy.location('pathname').should('equal', '/')
|
||||
|
||||
// Confirm that the user is logged out
|
||||
cy.contains('a', 'Log in')
|
||||
})
|
||||
})
|
||||
7
ui/tests/e2e/specs/home.e2e.js
Normal file
7
ui/tests/e2e/specs/home.e2e.js
Normal file
@@ -0,0 +1,7 @@
|
||||
describe('Home Page', () => {
|
||||
it('has the correct title and heading', () => {
|
||||
cy.visit('/')
|
||||
cy.title().should('equal', 'Home | Hammond')
|
||||
cy.contains('h1', 'Home Page')
|
||||
})
|
||||
})
|
||||
33
ui/tests/e2e/specs/profile.e2e.js
Normal file
33
ui/tests/e2e/specs/profile.e2e.js
Normal file
@@ -0,0 +1,33 @@
|
||||
describe('Profile Page', () => {
|
||||
it('redirects to login when logged out', () => {
|
||||
cy.visit('/profile')
|
||||
cy.location('pathname').should('equal', '/login')
|
||||
})
|
||||
|
||||
it('nav link exists when logged in', () => {
|
||||
cy.logIn()
|
||||
cy.contains('a', 'Logged in as Vue Master').should(
|
||||
'have.attr',
|
||||
'href',
|
||||
'/profile'
|
||||
)
|
||||
})
|
||||
|
||||
it('shows the current user profile when logged in', () => {
|
||||
cy.logIn()
|
||||
cy.visit('/profile')
|
||||
cy.contains('h1', 'Vue Master')
|
||||
})
|
||||
|
||||
it('shows non-current users at username routes when logged in', () => {
|
||||
cy.logIn()
|
||||
cy.visit('/profile/user1')
|
||||
cy.contains('h1', 'User One')
|
||||
})
|
||||
|
||||
it('shows a user 404 page when looking for a user that does not exist', () => {
|
||||
cy.logIn()
|
||||
cy.visit('/profile/non-existant-user')
|
||||
cy.contains('h1', /User\s+Not\s+Found/)
|
||||
})
|
||||
})
|
||||
19
ui/tests/e2e/support/commands.js
Normal file
19
ui/tests/e2e/support/commands.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// Create custom Cypress commands and overwrite existing ones.
|
||||
// https://on.cypress.io/custom-commands
|
||||
|
||||
import { getStore } from './utils'
|
||||
|
||||
Cypress.Commands.add(
|
||||
'logIn',
|
||||
({ username = 'admin', password = 'password' } = {}) => {
|
||||
// Manually log the user in
|
||||
cy.location('pathname').then((pathname) => {
|
||||
if (pathname === 'blank') {
|
||||
cy.visit('/')
|
||||
}
|
||||
})
|
||||
getStore().then((store) =>
|
||||
store.dispatch('auth/logIn', { username, password })
|
||||
)
|
||||
}
|
||||
)
|
||||
17
ui/tests/e2e/support/setup.js
Normal file
17
ui/tests/e2e/support/setup.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// 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'
|
||||
2
ui/tests/e2e/support/utils.js
Normal file
2
ui/tests/e2e/support/utils.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// Returns the Vuex store.
|
||||
export const getStore = () => cy.window().its('__app__.$store')
|
||||
Reference in New Issue
Block a user