-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #320 from platformsh-templates/feat/319-e2e-tests
Feat/319 e2e tests
- Loading branch information
Showing
11 changed files
with
2,420 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const { defineConfig } = require("cypress"); | ||
|
||
module.exports = defineConfig({ | ||
projectId: "ycsbj5", | ||
|
||
e2e: { | ||
baseUrl: 'https://localhost', | ||
env: { | ||
environment: 'local', | ||
test_user: 'bobby', | ||
test_user_pass: '123', | ||
}, | ||
setupNodeEvents(on, config) { | ||
// implement node event listeners here | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
const newPost = { | ||
"title": "New post from E2E", | ||
"body": "this is a new post created from e2e testing" | ||
} | ||
describe("Editor can log in and post", ()=>{ | ||
before(()=>{ | ||
cy.createUser(Cypress.env('test_user')) | ||
}) | ||
|
||
it("can navigate to log in page", ()=>{ | ||
cy.visit("/login") | ||
cy.url().should('match',/\//).should('include','wp-login.php') | ||
}) | ||
|
||
|
||
it('Can login via custom function', ()=>{ | ||
cy.wplogin(Cypress.env('test_user'),Cypress.env('test_user_pass')); | ||
cy.visit('/wp-admin/') | ||
cy.get('#wp-admin-bar-my-account').contains(Cypress.env('test_user')).should('exist') | ||
}) | ||
|
||
// it('can navigate to the posts page', ()=>{ | ||
// cy.get('#menu-posts').invoke('show') | ||
// | ||
// }) | ||
|
||
it('Can navigate to new posts page',()=>{ | ||
cy.wplogin(Cypress.env('test_user'),Cypress.env('test_user_pass')); | ||
cy.visit('/wp-admin/post-new.php') | ||
cy.get('#editor').should('exist') | ||
|
||
}) | ||
|
||
it('Can add and view a new post ', ()=> { | ||
cy.wplogin(Cypress.env('test_user'),Cypress.env('test_user_pass')) | ||
cy.visit('/wp-admin/post-new.php') | ||
cy.get('button[aria-label="Options"]').click() | ||
cy.get('div[class="components-menu-group"]').find('button').contains('Code editor').click() | ||
cy.get('#inspector-textarea-control-0').type(newPost.title) | ||
cy.get('#post-content-0').type(newPost.body) | ||
|
||
//yes, this is brittle but there aren't any id's and very few other identifiers to target these elements | ||
//cy.get('div[class="edit-post-text-editor__toolbar"]').find('button').contains('Exit code editor').click() | ||
cy.get('div[class="editor-text-editor__toolbar"]').find('button').contains('Exit code editor').click() | ||
cy.get('#editor').find('button').contains('Publish').click() | ||
//now we have ANOTHER panel that displays and asks us to click ANOTHER publish button | ||
cy.get('div[class="editor-post-publish-panel"]').as('publishpanel') | ||
|
||
cy.get('@publishpanel').find('button').contains('Publish').click() | ||
|
||
//now we need to verify it has published | ||
cy.get('@publishpanel').find('a').contains('View Post').as('viewpost').should('exist') | ||
cy.get('@viewpost').click() | ||
cy.get('body') | ||
.find('h1').contains(newPost.title).should('exist') | ||
|
||
//cy.get('[aria-label="Add title"]').click().type('Hello!') | ||
}) | ||
|
||
it('can delete their own posts', ()=>{ | ||
// Auth and get session | ||
cy.wplogin(Cypress.env('test_user'),Cypress.env('test_user_pass')) | ||
// Programmatically add a post so we can delete it | ||
cy.addPostForUser(Cypress.env('test_user'),newPost) | ||
cy.visit('/wp-admin/edit.php') | ||
// our post should be here | ||
cy.get('#the-list').find('[data-colname="Title"]').contains(`${newPost.title} test`).should('exist') | ||
// this should yield the a element. we want its parent element that is a td | ||
cy.get('#the-list').find('[data-colname="Title"]').contains(`${newPost.title} test`).as('ourPost') | ||
//cy.get('#the-list').find('[data-colname="Title"]').contains(`${newPost.title} test`).click() | ||
cy.get('@ourPost').parents('td[data-colname="Title"]').as('ourCell') | ||
// | ||
//cy.get('@ourCell').find('div[class="row-actions"]').invoke('show') | ||
cy.get('@ourCell') | ||
.find('span[class="trash"]').contains('Trash') | ||
/** | ||
* @todo find out exactly what event causes this section to be visible | ||
* this anchor is in a div, which has a left setting of -9XXXX. some event then removes that setting allowing it | ||
* to become visible. So far I've been unable to determine the element + event that triggers it to be visible | ||
* setting it to force:true for now since if you're using a screen reader you can still access it with the tab | ||
* key even though it isnt visible | ||
*/ | ||
.click({force: true}) | ||
|
||
cy.get('#message').should('contain','1 post moved to the Trash') | ||
|
||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
describe("Search", ()=>{ | ||
beforeEach(()=>{ | ||
cy.request({url: '/foobar', failOnStatusCode: false}).its('status').should('equal', 404) | ||
cy.visit('/foobar', {failOnStatusCode: false}) | ||
}) | ||
context("Search tests", () => { | ||
it("Visits a random page",()=>{ | ||
cy.request({url: '/foobar', failOnStatusCode: false}).its('status').should('equal', 404) | ||
cy.visit('/foobar', {failOnStatusCode: false}) | ||
cy.get('h1[class="page-title"]').should("exist").contains("Nothing here") | ||
}) | ||
|
||
it("Runs search from 404", ()=>{ | ||
cy.get("#search-form-1").type("Sample{enter}") | ||
//cy.get('[aria-label="Search"]').click() | ||
cy.location().should((loc)=>{ | ||
expect(loc.pathname).to.equal('/') | ||
expect(loc.search).to.equal('?s=Sample') | ||
}) | ||
|
||
cy.get('main').as('main') | ||
cy.get('@main').find('h1').contains('Results for').should('exist') | ||
cy.get('@main').find('h2').contains('Sample Page').should('exist') | ||
|
||
|
||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"title": "New post from E2E", | ||
"body": "this is a new post created from e2e testing" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
// *********************************************** | ||
// 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 will overwrite an existing command -- | ||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) | ||
/** | ||
* Authenticates a user programmatically | ||
*/ | ||
Cypress.Commands.add('wplogin',(username,password)=>{ | ||
|
||
Cypress.log({ | ||
name: 'wplogin', | ||
message: `${username}`, | ||
}) | ||
|
||
cy.session(username, ()=>{ | ||
cy.request({ | ||
method: 'POST', | ||
url: 'wp-login.php', | ||
form: true, | ||
body: { | ||
log: username, | ||
pwd: password, | ||
redirect_to: '', | ||
rememberme: '', | ||
testcookie: 1, | ||
'wp-submit': 'Log In', | ||
} | ||
}) | ||
}) | ||
}) | ||
|
||
/** | ||
* Resets state for our test user | ||
* If a user exists: | ||
* - Removes any stored session data for the user | ||
* - Deletes the user's posts | ||
* - Deletes the user | ||
*/ | ||
Cypress.Commands.add('beforeCreateUser', (username) => { | ||
const cmdPrefix = determineOurCmdPrefix() | ||
console.log('starting function beforeCreateUser') | ||
//const cmdUserFind = `${cmdPrefix} wp user list --login="${username}" --field=ID` | ||
console.log('Calling function findUser ') | ||
cy.findUser(username).then((data)=>{ | ||
if(data.id !== '') { | ||
console.log(`user ${username} exists and has an ID of ${data.id}`) | ||
//delete their posts before we delete them | ||
console.log('calling function findUserPosts ') | ||
cy.findUserPosts(data.id).then((posts)=>{ | ||
if(posts.length > 0) { | ||
console.log(`we have posts to delete for user ${data.id}. List of posts to delete:`) | ||
console.log(posts) | ||
const deletePosts = posts.join(' ') | ||
const cmdDeletePosts = `${cmdPrefix} 'wp post delete ${deletePosts}'` | ||
cy.exec(cmdDeletePosts).its('code').should('eq',0) | ||
} | ||
}) | ||
Cypress.session.clearAllSavedSessions() | ||
const cmdUserDelete = `${cmdPrefix} 'wp user delete ${data.id} --yes'` | ||
cy.exec(cmdUserDelete).its('code').should('eq',0) | ||
} | ||
}) | ||
}) | ||
|
||
/** | ||
* Creates a new test user account in our WordPress instance | ||
*/ | ||
Cypress.Commands.add('createUser', (username, role="editor") => { | ||
cy.beforeCreateUser(username) | ||
const vendor = Cypress.env('environment') | ||
const cmdPrefix = determineOurCmdPrefix() | ||
|
||
const cmdUserCreate = `${cmdPrefix} 'wp user create ${username} ${username}@mail.com --role=${role} --send-email=false --quiet'` | ||
|
||
cy.exec(cmdUserCreate).should((response) => { | ||
expect(response.code).to.equal(0) | ||
expect(response.stdout).to.contain('Password:') | ||
}).then(($response)=>{ | ||
//console.log('evaluating what the returned password is: ') | ||
//console.log(`stdout is : ${$response.stdout}`) | ||
const pswrd = $response.stdout.match(/^Password: (.*)$/) | ||
//console.log('Setting the new password.') | ||
Cypress.env('test_user_pass',pswrd[1]) | ||
cy.findUser(username).then((userdata)=>{ | ||
cy.setWelcomePref(userdata.id) | ||
}) | ||
}) | ||
}) | ||
|
||
/** | ||
* Retrieves a user id based on their username | ||
*/ | ||
Cypress.Commands.add('findUser', (username) => { | ||
console.log('starting function findUser') | ||
const vendor = Cypress.env('environment') | ||
const cmdPrefix = determineOurCmdPrefix() | ||
|
||
const cmdUserFind = `${cmdPrefix} 'wp user list --login="${username}" --field=ID'` | ||
cy.exec(cmdUserFind).then((response)=>{ | ||
const returnData = {id:''} | ||
if(response.stdout !== ''){ | ||
returnData.id = response.stdout | ||
} | ||
console.log('Leaving function findUser') | ||
return returnData | ||
}) | ||
}) | ||
|
||
/** | ||
* Finds the list of posts for a given userID | ||
*/ | ||
Cypress.Commands.add('findUserPosts', (userID) => { | ||
const cmdPrefix = determineOurCmdPrefix() | ||
let posts = [] | ||
console.log('starting function findUserPosts') | ||
const cmdFindUserPosts = `${cmdPrefix} 'wp post list --field=ID --post_author=${userID} --format=json'` | ||
cy.exec(cmdFindUserPosts).then((response)=>{ | ||
/** | ||
* we should get a string in JSON format. if no posts were found we should get [] | ||
*/ | ||
const possiblePosts = JSON.parse(response.stdout) | ||
if(possiblePosts.length > 0) { | ||
posts = possiblePosts | ||
} | ||
|
||
return posts | ||
}) | ||
}) | ||
|
||
/** | ||
* Creates a post for a user | ||
* Used for testing if a user can delete their own posts | ||
*/ | ||
Cypress.Commands.add('addPostForUser',(username, postObject)=>{ | ||
const cmdPrefix = determineOurCmdPrefix() | ||
console.log(`Adding a post for user ${username}`) | ||
cy.findUser(username).then((user)=>{ | ||
expect(user.id).to.not.equal('') | ||
const cmdNewPost = `${cmdPrefix} 'wp post create --post_title="${postObject.title} test" --post_content="${postObject.body}" --post_author=${user.id} --post_status=publish'` | ||
cy.exec(cmdNewPost).its('code').should('eq',0) | ||
}) | ||
}) | ||
|
||
/** | ||
* Sets the user pref to not display the welcome message in the post editor screen | ||
*/ | ||
Cypress.Commands.add('setWelcomePref',(userid)=>{ | ||
const cmdPrefix = determineOurCmdPrefix() | ||
const userMetaPrefsKey = 'wp_persisted_preferences' | ||
const cmdGetPrefs = `${cmdPrefix} 'wp user meta get ${userid} ${userMetaPrefsKey} --format=json'` | ||
console.log(`Getting user prefs for use ${userid}`) | ||
cy.exec(cmdGetPrefs,{failOnNonZeroExit: false}).then((response)=>{ | ||
//expect(response.code).to.eq(0) | ||
let prefs = {} | ||
if ('' != response.stdout) { | ||
prefs = JSON.parse(response.stdout) | ||
} | ||
|
||
if(!Object.hasOwn(prefs,'core/edit-post')) { | ||
console.log('prefs does not have core-edit-property. setting.') | ||
//Object.defineProperty(prefs, 'core/edit-post',{}) | ||
prefs['core/edit-post'] = {} | ||
} | ||
|
||
if(!Object.hasOwn(prefs['core/edit-post'],'welcomeGuide')) { | ||
console.log('prefs.core-edit-post does not have property welcomeGuide. Setting to false') | ||
//Object.defineProperty(prefs['core/edit-post'],'welcomeGuide',false) | ||
prefs['core/edit-post'].welcomeGuide = false | ||
} else { | ||
console.log('prefs.core-edit-post.welcomeGuide exists! Setting to false') | ||
prefs['core/edit-post'].welcomeGuide = false | ||
} | ||
|
||
const prefsToSave = JSON.stringify(prefs) | ||
const cmdSavePrefs = `PREFS='${prefsToSave}' && ${cmdPrefix} "wp user meta update ${userid} ${userMetaPrefsKey} '$PREFS' --format=json"` | ||
console.log(`Saving user prefs for user ${userid}`) | ||
cy.exec(cmdSavePrefs).its('code').should('eq',0) | ||
}) | ||
}) | ||
|
||
const determineOurCmdPrefix = () => { | ||
const vendor = Cypress.env('environment') | ||
let cmdPrefix = ''; | ||
switch (vendor) { | ||
case 'ddev': | ||
case 'local': | ||
cmdPrefix = 'ddev exec' | ||
break; | ||
default: | ||
cmdPrefix = `${vendor} ssh` | ||
} | ||
|
||
return cmdPrefix | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// *********************************************************** | ||
// This example support/e2e.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') | ||
|
||
Cypress.on('uncaught:exception', (err, runnable) => { | ||
// we expect a 3rd party library error with message 'list not defined' | ||
// and don't want to fail the test so we return false | ||
if (err.message.includes("Cannot destructure property 'documentElement' of 'o'")) { | ||
return false | ||
} | ||
// we still want to ensure there are no other unexpected | ||
// errors, so we let them fail the test | ||
}) |
Oops, something went wrong.