赛普拉斯登录与重定向

voh*_*tom 1 session-cookies cypress cypress-login

我想创建执行以下操作的 Cypress 脚本:

  1. 登录平台
  2. 存储以下测试的会话 - 因此我不必在每次执行新测试时都登录
  3. 执行其余测试

1. 可以工作,但不理想

当我通过访问启动脚本时,我确实设法让它工作

cy.visit('https://localhost:3000/login')
Run Code Online (Sandbox Code Playgroud)

但后来我有两个问题:

A. 其余代码需要位于 origin 函数中:

cy.origin('https://localhost:3000/login', () => {
    cy.visit('https://localhost:3000')
    // test script
})
Run Code Online (Sandbox Code Playgroud)

B、更重要的是:

  • 它不保留会话
  • 多次登录后,用户以某种方式停止工作并且不再通过平台进行身份验证。

2. 不工作,理想

所以我想通过访问以正确的方式启动脚本

cy.visit('https://localhost:3000/')
Run Code Online (Sandbox Code Playgroud)

然后点击Log In按钮

cy.contains('Log In')
    .click()
Run Code Online (Sandbox Code Playgroud)

这是棘手的部分 - 一旦用户单击按钮,Log InURL https://localhost:3000/login(状态代码302)会将用户重定向到

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
Run Code Online (Sandbox Code Playgroud)

一旦我让脚本以这种方式工作,我就会遇到两个问题:

A。Chrome 要求我允许重定向

b. 一旦允许,我将被重定向到 Cypress 之外,因此左侧边栏完全消失

赛普拉斯侧边栏不见了

有人知道如何解决这个问题吗?

整个代码是

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})
    })

})
Run Code Online (Sandbox Code Playgroud)

我尝试检查 Gleb 的 YouTube视频以及 Cypress文档,但我没能成功:-(

我还尝试创建代码的较小部分,例如

it('Homepage', () => {
    cy.visit('https://localhost:3000')
})


it('Login', () => { 
    cy.visit('https://localhost:3000/login')
    // Login code
})

it('Test', () => {  
    // Do sth once logged in
})
Run Code Online (Sandbox Code Playgroud)

但当我尝试这种方式时,我没有被授权为用户。

我的cypress.config.js文件中有这个:

"experimentalSessionAndOrigin": true

关于如何解决它有什么想法、技巧吗?非常感谢您提前!

Fod*_*ody 5

您的代码非常接近,这就是我认为您需要更改的内容。

避免帧破坏

您应该能够通过直接在cy.session().

cy.session() 的调用模式

cy.session()应该在 a 中beforeEach()而不是 a 中before()。它的目的是恢复每个 的 auth cookie it(),因此必须在每次测试之前调用它。

访问每个测试顶部的主 URL

cy.visit('https://localhost:3000')每次测试都需要,请参阅会话

由于页面在每次测试开始时都会被清除,因此必须在每次测试开始时显式调用 cy.visit()。

不需要原点命令

cy.origin()https://staging.XXX.com/login当两个源位于不同的执行块中(即在beforeEach()和块https://localhost:3000中)时,不需要it()


这是一般模式,为了清楚起见,我省略了一些行

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
        ...
    })
})
Run Code Online (Sandbox Code Playgroud)