我在尝试在 gitlab ci 中运行 cypress 时遇到了麻烦。在本地,当我尝试通过 cypress open 或 run 命令运行测试时,一切似乎都运行顺利。
导致错误的主要原因是最初的弹出窗口,有时会提示用户需要注销。在本地,它重定向到登录页面。为了实现这一点,代码开头的
cy.wait(1000)
是必要的。我在官方文档中没有找到这个
你可能会看到在 CI Pipeline 中我什至等待了 4000ms
在
cypress/support/e2e.js
文件中,我有以下代码在每次测试之前运行
function loginViaAAD(username, password) {
cy.visit('http://localhost:3000/');
// Sometimes the tests opens the "Logout" page, but if we wait
// it goes away and loads the log in page automatically
cy.wait(1000);
// Login to your AAD tenant.
cy.origin(
'login.microsoftonline.com',
{
args: {
username,
},
},
({ username }) => {
cy.get('input[type="email"]').type(username, {
log: false,
});
cy.get('input[type="submit"]').click();
},
);
// depending on the user and how they are registered with Microsoft, the origin may go to live.com
cy.origin(
'login.microsoftonline.com',
{ args: { password } },
({ password }) => {
cy.get('input[type="password"]').type(password, { log: false });
cy.get('input[type="submit"]').click();
cy.wait(2000);
},
);
cy.origin('login.microsoftonline.com', () => {
cy.task('generateOTP').then((otp) => {
// Enter OTP
cy.get('#idTxtBx_SAOTCC_OTC').type(otp);
cy.get('#idSubmit_SAOTCC_Continue').click();
cy.wait(2000);
// case where the pop up appears with the "Stay signed in" message
cy.get('body').then((body) => {
if (body.find('#KmsiCheckboxField')) {
cy.get('#KmsiCheckboxField').click(); // checkbox
cy.get('#idSIButton9').click(); // yes button
cy.wait(2000);
}
});
});
});
}
Cypress.Commands.add('loginToAAD', (username, password) => {
cy.session(
`AAD-${username}`,
() => {
const log = Cypress.log({
displayName: 'Azure Active Directory Login',
message: [`Authenticating | ${username}`],
autoEnd: false,
});
log.snapshot('before');
loginViaAAD(username, password);
log.snapshot('after');
log.end();
},
{
validate: () => {
// this is a very basic form of session validation.
cy.visit('http://localhost:3000');
cy.get('.header__avatar-name').should(
'contain',
`${Cypress.env('AAD_FULLNAME')}`,
);
},
},
);
});
before(() => {
cy.log(Cypress.env('AAD_USERNAME'));
// log into Azure Active Directory through our sample SPA using our custom command
cy.loginToAAD(Cypress.env('AAD_USERNAME'), Cypress.env('AAD_PASSWORD'));
cy.visit('http://localhost:3000');
});
这就是我的 CI 工作
e2e-tests:
image: cypress/browsers:node-20.14.0-chrome-126.0.6478.114-1-ff-127.0.1-edge-126.0.2592.61-1
stage: test
before_script:
- npm ci --cache .npm --prefer-offline
script:
- npm run linux_start &
- npx cypress run --browser chrome --env AAD_USERNAME=$AAD_USERNAME,AAD_FULLNAME=$AAD_FULLNAME,AAD_PASSWORD=$AAD_PASSWORD,TOTP_SECRET=$TOTP_SECRET
artifacts:
when: always
paths:
- cypress/videos/**/*.mp4
- cypress/screenshots/**/*.png
expire_in: 1 day
忽略 CI 中的环境变量似乎未定义。
该错误可能是由于 cy.wait() 命令不足以确保弹出窗口消失并且登录页面加载到 CI 管道中。 CI作业中,cy.wait()命令设置为4000ms,比本地使用的1000ms长。
发布答案以帮助社区:
在您的场景中,错误是因为您没有传递 msal 的错误配置。
要解决错误,请传递环境变量,如下所示:
cypress.env.json
{
"aad_username": "AAD_USERNAME",
"aad_password": "AAD_PASSWORD",
"aad_name": "AAD_NAME"
}
并使用以下脚本执行Azure AD身份验证:
describe('Azure Active Directory Authentication', () => {
beforeEach(() => {
// log into Azure Active Directory through our sample SPA using our custom command
cy.loginToAAD(Cypress.env('aad_username'), Cypress.env('aad_password'))
cy.visit('http://localhost:3000')
})
it('verifies the user logged in has the correct name', () => {
cy.get('#table-body-div td:contains("name") + td').should(
'contain',
`${Cypress.env('aad_name')}`
)
})
it('verifies the user logged in has the correct preferred name', () => {
cy.get('#table-body-div td:contains("preferred_username") + td').should(
'contain',
`${Cypress.env('aad_username')}`
)
})
})
参考: