Я хочу щелкнуть несколько элементов на веб-странице и проверить, создает ли каждое из этих действий правильный URL-адрес запроса API. Для этого я создал массив настроек для каждого элемента и перебрал их, щелкнул соответствующий элемент и подтвердил результаты. Проблема в том, что утверждение для последнего элемента всегда ожидает установки для первого элемента. Я вижу, что это происходит потому, что кипарис работает асинхронно. Итак, я удалил итерацию и просто повторил все утверждения-действия, как показано ниже.
Есть ли простой способ сделать синхронный цикл for вместо того, как я это сделал ниже? По сути, я хочу преобразовать последовательность .then() в цикл for. «Действие» — это нажатие элемента на странице на основе объекта actionSettings. Этот объект может выглядеть примерно так: {age: 23, gender: male}. ОБРАТИТЕ ВНИМАНИЕ, что я не хочу использовать здесь плагин рекурсии кипариса.
//code to intercept api call aliased as "actionApiCall".
cy.log("Do 1 of 5 actions on a given page")
.then(() => {
const actionSettings = getActionSettings("for action 1");
myPageObject
// clickElement(...) returns a Cypress.Chainable<null> with return cy.wrap(null);
.clickElement(actionSettings)
.wait("@actionApiCall")
.then((intercept) => {
// This assertion checks that the query params of the request URL are per the settings in actionSettings.
AssertActions.assertActionRequest(intercept.request, actionSettings);
});
}).log("Do 2 of 5 actions on a given page")
.then(() => {//do stuff})
.log("Do 3 of 5 actions on a given page")
.then(() => {//do stuff})
..... ETC
PS — Cypress .each здесь не будет работать, потому что я не хочу перебирать элементы кипариса. Я хочу перебирать массив «actionSettings», то есть не элементы кипариса. Кроме того, вот решения, которые мне не помогли.
Как я могу запустить команду Cypress в синхронном цикле?
Какие именно действия? Есть ли другие методы AssertActions.assertActionRequest? то есть не могли бы вы примерно показать, что такое do stuff для №2 и №3, пожалуйста?
@AngusYaam - спасибо. Да, я хочу преобразовать последовательность .then() в цикл for. Действия для №2 и №3 в основном такие же, как и для №1. «Действие» — это действие по щелчку элемента на странице на основе объекта actionSettings. Этот объект может выглядеть примерно так: {age: 23, gender: male}. Пожалуйста, дайте мне знать, если это поможет, или мне нужно объяснить это лучше.
Хорошо, спасибо, думаю, теперь я вижу закономерность.
Я не могу опубликовать код, но использую Аладина - массив для цикла будет выглядеть примерно так ['for action 1', 'for action 2', 'for action 3']. Затем я помещал общий код в функцию и передал каждую клавишу действия в качестве параметра (это все простой forEach() код). Я согласен с комментариями о создании утверждений для «регулирования» потока, которые кажутся правильным способом заставить цикл вести себя синхронно.






Я думаю, вы просто хотите обернуть каждый шаг в .then(), чтобы гарантировать, что очередь Cypress обрабатывается в том же порядке, что и ваша последовательность выше.
Не думайте о асинхронности/синхронности, вместо этого подумайте об очереди команд, которую Cypress использует в качестве конвейера команд. Когда вы выполняете цикл по некоторому массиву, использование .then() гарантирует, что команды находятся в правильной последовательности.
Если действие вызывает изменение страницы, вам нужно будет добавить после каждого утверждения утверждение should(), подтверждающее завершение действия.
Что-то вроде:
const actionsArray = [action1, action2, action3]
actionsArray.forEach(action => {
cy.then(() => {
action() // perform action in sequence
.should(assert action is complete)
})
})
// or
cy.wrap(actions).each(action => {
cy.then(() => {
action() // perform action in sequence
.should(assert action is complete)
})
})
логически эквивалентно
action1()
.should(assert something that indicates action1 is complete)
.then(() => {
action2().should(assert action is complete)
})
.then(() => {
action3().should(assert action is complete)
})
Есть и другие вопросы, которые следует учитывать, например, что делать, если действия зависят от некоторых данных, которые обновляются на разных этапах.
Похоже, ваш массив действий будет массивом функций для запуска. Это верно? Почему мы не можем вместо этого перебирать actionSettings? actionsettings — это объект типа {age: 23, gender: male}
Да, извините, я неправильно понял вопрос.
Я должен сказать, что ответы на связанные вопросы в основном предлагают альтернативные способы выполнения цикла, хотя на самом деле основное внимание должно быть уделено управлению кодом внутри цикла - обеспечению завершения каждой итерации перед запуском следующей.
Многие детали скрыты вашим пользовательским кодом, и мы можем только догадываться, что он делает. Полагаю, вы спрашиваете: «Как мне преобразовать последовательность
.then()в цикл».