I would like to create Cypress script that does the following:
1. WORKING, but not ideal
I did manage to make it work when I start the script by visiting
cy.visit('https://localhost:3000/login')
but then I have two problems:
A. Rest of the code needs to be in the origin function:
cy.origin('https://localhost:3000/login', () => {
cy.visit('https://localhost:3000')
// test script
})
B. More important:
2. NOT WORKING, ideal
So I wanted to start the script the proper way by visiting
cy.visit('https://localhost:3000/')
then clicking on the Log In
button
cy.contains('Log In')
.click()
and here is the tricky part - Once the user clicks to the Log In
button the URL is https://localhost:3000/login
(Status Code 302) redirects the user to
https://staging.XXX.com/login?redirect_uri=https%3A%2F%2Flocalhost%3A3000%2Freturn_from_login&client_id=CLIENT_ID&scope=%7B%22full%22%3A+true%7D
and once I am making the script working that way I have two problems:
a. Chrome asks me to allow redirect
b. Once allowed, I am redirected outside of the Cypress so the left sidebar disappears completely
Does anybody know how to solve this?
The whole code is
describe('User Session + Start a Discussion', () => {
const username = "username";
const password = "password";
before(() => {
cy.session("User Session", () => {
cy.visit('https://localhost:3000')
cy.contains('Log In')
.click()
cy.contains('Allow All Cookies', { timeout: 60000 })
.should('be.visible')
cy.contains('Allow All Cookies')
.click()
cy.get('input[placeholder="Username or Email"]')
.type(username)
cy.contains('Next')
.click()
cy.get('input[placeholder="Password"]')
.type(password)
cy.contains('Log In')
.click()
cy.get('button[data-bind="html: actionButtonHTML, click: consentToGrantAction, disable: busy"]', { timeout: 120000 })
.should('be.visible')
cy.get('button[data-bind="html: actionButtonHTML, click: consentToGrantAction, disable: busy"]')
.click()
})
})
it('Starts a new Discussion', () => {
cy.visit('https://localhost:3000')
cy.get('a[href="/discussions"]', { timeout: 120000 }).should('be.visible')
cy.get('a[href="/discussions"]')
.click()
cy.contains('Start a discussion', { timeout: 20000})
.click()
cy.contains('Attach to Discussion...')
.click()
cy.get('#object-selector-modal-1').should('be.visible')
cy.get('[data-classname="file"]')
.click()
cy.get(':nth-child(1) > .media > .media-body > label > input')
.click()
cy.get('[data-bind="click: save, css: {disabled: !canSave()}, disable: !canSave()"]')
.click()
cy.get('textarea[class="ace_text-input"]')
.type("New Discussion", {force: true})
cy.contains('Publish')
.click({force: true})
cy.contains('Publish selected objects')
.click({force: true})
})
})
I tried to check Gleb's youtube vids and also Cypress documentation but I did not manage to make it work :-(
I was also trying to create as a smaller parts of the code like
it('Homepage', () => {
cy.visit('https://localhost:3000')
})
it('Login', () => {
cy.visit('https://localhost:3000/login')
// Login code
})
it('Test', () => {
// Do sth once logged in
})
But I was not authorized as the user when I tried that this way..
I have this in my cypress.config.js file:
"experimentalSessionAndOrigin": true
Any ideas, tips on how to solve it? Big thank you in advance!
Your code is pretty close, here's what I think you need to change.
Avoiding frame-busting
You should be able to avoid the redirect jumping out of the Cypress runner by visiting it directly inside the cy.session()
.
Calling pattern for cy.session()
cy.session()
should be in a beforeEach()
not a before()
. It's purpose is to reinstate the auth cookies for each it()
, so it must be called before each test.
Visit main URL at the top of each test
cy.visit('https://localhost:3000')
is required for every test, see session
Because the page is cleared at the beginning of each test, cy.visit() must be explicitly called at the beginning of each test.
Origin command isn't required
cy.origin()
is not required when the two origins are in different execution blocks, i.e https://staging.XXX.com/login
in the beforeEach()
and https://localhost:3000
in the it()
block.
Here is the general pattern, I've left out some lines for clarity
describe('User Session + Start a Discussion', () => {
beforeEach(() => {
cy.session("User Session", () => {
cy.visit('https://staging.XXX.com/login')
cy.contains('Log In').click()
...
cy.get('input[placeholder="Username or Email"]').type(username)
cy.contains('Next').click()
cy.get('input[placeholder="Password"]').type(password)
cy.contains('Log In').click()
...
})
})
it('Starts a new Discussion', () => {
cy.visit('https://localhost:3000') // logged-in state
...
})
it('Further test', () => {
cy.visit('https://localhost:3000') // logged-in state
...
})
})