Over the internet the login page reloads once on a first visit (service worker taking control) and can move the focus back to the username field while it settles; both made logins fail at random (8.2.4 and 8.3.0). ayLogin now lets the service worker take control first, waits for notify/hello and the trial users list, checks both fields and types again if needed, and clicks the login button. 0900 reloads Notifications until the notification arrives (the server delivers about once a minute). 27/27 on the 8.3.0 release candidate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
127 lines
4.6 KiB
JavaScript
127 lines
4.6 KiB
JavaScript
// ***********************************************
|
|
// 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) => { ... })
|
|
|
|
//For firefox only issue chrome ok when running all test since cypress v10
|
|
//https://docs.cypress.io/api/events/catalog-of-events#Uncaught-Exceptions
|
|
Cypress.on('uncaught:exception', (err, runnable, promise) => {
|
|
// when the exception originated from an unhandled promise
|
|
// rejection, the promise is provided as a third argument
|
|
// you can turn off failing the test in this case
|
|
if (promise) {
|
|
return false
|
|
}
|
|
// we still want to ensure there are no other unexpected
|
|
// errors, so we let them fail the test
|
|
})
|
|
|
|
|
|
Cypress.Commands.add("ayChooseVSelect", (dataCyTag, selectionText) => {
|
|
cy.get(`[data-cy='${dataCyTag}']`).click({ force: true });
|
|
cy.get(".v-list-item__title")
|
|
.contains(new RegExp("^" + selectionText + "$", "g"))
|
|
.click({ force: true });
|
|
});
|
|
|
|
Cypress.Commands.add("ayChooseGZPickList", (dataCyTag, selectionText) => {
|
|
cy.get(`[data-cy='${dataCyTag}']`).click({ force: true }).type(selectionText);
|
|
cy.get(".menuable__content__active")
|
|
.contains(new RegExp(selectionText))
|
|
.click();
|
|
});
|
|
|
|
Cypress.Commands.add("ayLogin", (user, urlAfterLogin) => {
|
|
if (!urlAfterLogin) {
|
|
urlAfterLogin = "/ay-evaluate";
|
|
}
|
|
// On a first visit to a built server the app's service worker installs, takes control and
|
|
// App.vue then reloads the page (controllerchange); a reload while typing fails the test.
|
|
// Let that happen first: wait until the service worker controls the page (at most 15 seconds,
|
|
// never failing; the local dev server has none), then open the login page again.
|
|
cy.visit("/login");
|
|
cy.window().then(
|
|
{ timeout: 20000 },
|
|
(win) =>
|
|
new Cypress.Promise((resolve) => {
|
|
const sw = win.navigator.serviceWorker;
|
|
if (!sw || sw.controller) {
|
|
return resolve();
|
|
}
|
|
const giveUp = setTimeout(resolve, 15000);
|
|
sw.addEventListener("controllerchange", () => {
|
|
clearTimeout(giveUp);
|
|
resolve();
|
|
});
|
|
})
|
|
);
|
|
|
|
// the login page fills in sample credentials and adds the trial users list above the
|
|
// username field when notify/hello answers (trial servers); wait for that first.
|
|
// The suite always runs on a seeded trial.
|
|
cy.intercept("GET", "**/notify/hello").as("hello");
|
|
cy.visit("/login");
|
|
cy.wait("@hello");
|
|
cy.get("[data-cy=selecttrialuser]");
|
|
|
|
ayFillLogin(Cypress.env(user).login, Cypress.env(user).password, 5);
|
|
|
|
// the button logs in with whatever is in the fields, wherever the keyboard focus is
|
|
cy.get("[data-cy=loginbutton]").click();
|
|
|
|
cy.url().should("include", urlAfterLogin);
|
|
});
|
|
|
|
// Over the internet the login page can still redraw while it settles, and on a first visit the
|
|
// service worker reloads it once (App.vue, controllerchange). A redraw moves the keyboard focus
|
|
// back to the username field (v-focus) mid-typing, a reload wipes both fields (both seen on 8.2.4
|
|
// and 8.3.0). So type, give any redraw under way a moment, check both fields, and type again if
|
|
// either is wrong.
|
|
function ayFillLogin(login, password, triesLeft) {
|
|
cy.get("input[name=username]").clear().type(login);
|
|
cy.get("input[name=password]").clear().type(password);
|
|
cy.wait(500);
|
|
cy.get("input[name=username]").then(($u) => {
|
|
cy.get("input[name=password]").then(($p) => {
|
|
if (($u.val() !== login || $p.val() !== password) && triesLeft > 0) {
|
|
ayFillLogin(login, password, triesLeft - 1);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
Cypress.Commands.add("ayChooseExistingTags", (dataCyTag, tagList) => {
|
|
for (let i = 0; i < tagList.length; i++) {
|
|
cy.get(`[data-cy='${dataCyTag}']`).click().type(tagList[i]);
|
|
cy.get(".v-list-item__mask");
|
|
cy.get(`[data-cy='${dataCyTag}']`).type("{downarrow}{enter}");
|
|
}
|
|
});
|
|
|
|
Cypress.Commands.add("aySetTestableUserOptions", () => {
|
|
cy.visit("/home-user-settings");
|
|
cy.url().should("include", "/home-user-settings");
|
|
cy.get("[data-cy='nativeDateTimeInput']").check({ force: true });
|
|
});
|