понедельник, 17 декабря 2018 г.

Задача 13

13. ( Продвинутый ) В задании No12, п.d.i параллельно с задачей “Проверка заявки” требуется
запустить подпроцесс. Данный процесс отслеживает состояние задачи. Если задача не
выполнена в 10:00 утра каждого дня, то процесс отправляет напоминание письмом на имя ответственного за договор, в противном случае процесс завершается. Используйте все
возможные инструменты для реализации данной задачи.

Итак, т.к. это подпроцесс, а подпроцессы всегда начинаются с простого входа, мы ставим входящий зеленый пустой кружочек.

Второй шаг - название самого БП. Вверху мы его назвали "Состояние задачи".

Третий шаг - мы сделали параметр

Выбрали вот такое:




Т.е. мы присвоили айдишник этой задачи, создали такую кагбэ переменную.
У нее название 'id задачи'
Код - я так понимаю, как эта переменная будет выглядеть в коде - 'ProcessSchemaParameter1'
Тип данных - "уникальный идентификатор".
Значение - мы не выбирали, т.к. это уже потом будет заполняться.




Потом мы считываем состояние задачи.




Сначала мы пишем на сером фоне название "Читать состояние задачи".

Какой режим чтения данных использовать?
Читать первую запись из выборки. (Разобраться, почему)

Как отфильтровать записи?

Т.е. мы фильтруем по id = id задачи. По тому параметру, который мы тогда выдумали.
Ну, и да, когда пишем фильтр, а именно там, где у меня выделено, оно предлагает выбрать этот параметр процесса. Тот самый, который мы тогда создали - уникальный айдишник.

Вот тут мы выбираем














Как отсортировать записи?
Соритровка по Заголовку и По возрастанию.

Значение каких колонок вычитать?
Всех колонок.


===============================
Потом зафигачиваем формулу.

Но чтобы в формулу запилить новые данные, нужна переменная. Мы ее создаем снова через голубенький параметр:

Идем в параметры и добавляем параметр "Время уведомления":
Пишем название "Время уведомления"
Код, как будет называться переменная - current time.
Тип данных выбираем из выпадашки ВРЕМЯ.
Значение тоже оставляем пустым.





Потом фигачим формулу с помощью того голубенького параметра, ну, переменной:





Название: "ВРЕМЯ уведомления"
В какой параметр передать значение формулы? Ну, в какую переменную записать?
Выбираем Current time - время уведомления, ту переменную, которую только что создали через параметры. Теперь она выдается там, в окошке выбора:











Задача 12

12. Создайте кейс в разделе “Заявки” (раздел был создан Вами в п.2):
a. Колонка, по которой будут строиться стадии кейса - [Состояние]. Используйте уже
внесенные значения справочника для создания стадий кейса. Стадии “Отменена” и
“Выполнена” должны быть сгруппированы (первой должна отображаться стадия
“Выполнена”).
b. Кейсы должны запускаться по категориям. Созданный Вами кейс должен запускаться
по категории “Фин. отдел”.Сертификация Бизнес Аналитика
c. На стадии “Новая” должна быть поставлена задача “Подготовить заявку к
согласованию” (категория “Письменная работа”, длительность - 30 мин, должна
отображаться в календаре).
d. На стадии “На рассмотрении” должны быть 2 шага. Для этого выполните следующие
действия:
i.
Создайте новую категорию активности “Проверка заявки”, для этой категории
создайте следующие результаты: “Подтверждено”, “Не подтверждено”.
ii.
Создайте задачу в кейсе “Проверить заявку” (задача должна отображаться в
календаре, ответственным по задаче должен быть ответственный по текущей
заявке). Данная задача должна ставиться в момент перехода на стадию и быть
обязательным шагом.
iii.
Создайте второй шаг “Отправить уведомление”. После выполнения активности
должно отправляться письмо.
В зависимости от результата, указанного в предыдущем шаге нужно
формулировать тему письма. В частности, если результат выполнения
активности из предыдущего пункта будет “Подтверждено” - в заголовке письма
должна быть фраза “Утверждение получено”. Если же результат “не
подтверждено” - фраза “Утверждение не получено”.
Совет: Для реализации данной задачи используйте тернарное выражение в
теме
письма
([#Проверить
заявку.Результат
активности#]==[#Справочник.Результат активности.Подтверждено#]) ?
"Утверждение получено":"Утверждение не получено"
iv.
Сделайте так, чтобы после отправки письма кейс переходил на следующую
стадию
“Визирование”
e. На стадии визирование нужно настроить следующую логику:
i.
Используйте шаг “Визирование” для отправки запроса на визирование.
Визирующим может быть любой сотрудник роли “Финансовый инспектор”. Этот
шаг должен быть обязательным. Если результат визирования положительный
- кейс должен перейти на стадию “Выполнена”. Если результат визирования
негативный или отмена - кейс переходит на стадию “Отменена”.
f. Стадии “Выполнена” и “Отменена”
i.
На этих стадиях право редактировать текущую заявку кейса имеют только
сотрудники роли “Финансовый инспектор”. Все остальные пользователи
системы могут только читать запись.
ii.
При перемещении на стадию “Отменена” прогресс-бар должен быть красного
цвета.






среда, 3 октября 2018 г.

Тэги, по которым я буду находить нужную инфу.

Отчеты: отчеты, базы данных, бд, запросы в бд, запросы в базу данных, работа с джирой, джира


Тэги для копипасты по разным темам


понедельник, 6 августа 2018 г.

Проверка, где зафейлилось, Селениум



В общем, чтобы проверить, в каком месте зафейлилось, надо добавлять строчки:

.then (()=> {console.log('****************************1')})


Так оно полегче как-то. Можно увидеть, где произошел краш.

1. В С. методы возвращают либо resolve, либо reject.
2. Мы пишем стрелочную функцию .then, где есть 2 парамтера.

.then(() => {          // 1-й параметр.
}, (err) => {
    console.log(err);   // 2-й параметр.
    testResult = false
}) 


у нас был вот такой код, мы там расставили вывод в консоль 1, 2, 3 ошибки.


Трабла была во втором. Вот вывод, который был в консольке:



Т.е. вывелось первое и третье. Почему? Потому что выводится только в случае успешного выполнения.
.then (()=> {console.log('****************************2')})
Код был такой. Т.е. только в случае resolove выводится эта строка с "2".

Разбираем второй случай.
Там сначала идет .getAttribute. Он проходит норм, там все хорошо.
А вот .setValue не проходит, т.к. у нас уже нет этого .input__control, поле для ввода задизэйблили.




Создание макросов, или автозамны, кароч, для автоматизации, Селениум

Зайти в Настройки - Live Templates - JS. Там уже менять.



понедельник, 23 июля 2018 г.

Linux, команды поиска: find, whereis, which, locate, whatis

http://www.linux-ink.ru/static/SL.5.1_Docs/Russification/Docs/sbs-sl-ru/s1-managing-locating.html

кошерная ссылка по поиску в терминале.

вторник, 17 июля 2018 г.

Мэнэджить меню в ВП.

1. Заходим в меню слева - внешний вид - меню. Там и можно менеджить.
Слева выбираем раздел, нажимаем "добавить в меню", а потом просто перетаскиваем куда надо


вторник, 3 июля 2018 г.

project = FA AND resolution = Unresolved AND "MVP Level" = 1 

пятница, 29 июня 2018 г.

Добавить тест-кейсы, джира

Сделать выборку по тестам, нажать more, выбрать за нужные дни.
Там мы поставили за последние 2 дня.

Оно предложило сохранить фильтр и дать ему название.



Потом надо пойти в Tests - Plan Test Cycle:



Там выбираем необходимый цикл, который нам нужен. Здесь Никита уже создал цикл, я туда просто добавила свои тест-кейсы:



Там при 'Add Tests' выскочило окошко, где я по фильтру, вроде вторая опция, нашла тест-кейсы, которые мне нужны и добавила их в этот цикл тестирования

четверг, 14 июня 2018 г.

Спулить изменения в гите, git pull

Спулить - значит стянуть те изменения, которые делали другие камрады.
Мы делаем сейчас тесты в папочке тестов.
Итак, мы делаем ПКМ по папочке с тестами, в контекстном меню выбираем Git - Repository - Stash Changes.
Почему не Pull, а Stash Changes?
Stash - скрыть.
Т.к. у меня самой были изменения, я их скрываю, дабы они тоже не запулились, как-то так, да?
Значит сначала я делаю Stash Changes. Как-нибудь их называю на всякий случай.

Потом иду и снова делаю:
ПКМ по папочке с тестами, в контекстном меню выбираем Git - Repository - Pull. Т.к. у нас были изменения в конфигах, появилась табличка, где были отображено три столбика, где отмечены все изменения.
1-й столбик был с изменениями Никиты, второй столбик - Result (то, что у меня в итоге будет), третий столбик - мой файл конфига.
Красненьким отмечены изменения, типа, чего не хватает, а голубеньким - что-то дополнительное, добавленное.
Там напротив каждого изменения крестик и стрелочки, типа, добавить в Result. Я выбираю че добавить, че не добавить.

Потом делаю снова:
ПКМ по папочке с тестами, в контекстном меню выбираем Git - Repository - Unstash Changes.



вторник, 29 мая 2018 г.

Установка виндоус и убунту, dual boot, grub, UEFI, разметка разделов, gpt, менеджер загрузки, HP, урезанный биос и прочие радости :)

В общем, напишу на всякий пожарный маленький ман для себя, как пришлось устанавливать винду и линукс и какие траблшуты пришлось приодолеть в связи с тем, что надо было делать все в режиме UEFI с разбивкой разделов gpt. Ну, и ноут HP был с урезанным биосом.

1. Записываем установочную флешку, у меня было через unetbootin.
2. Заходим в LiveCD и вызываем в терминале gparted. Есичо, Ctrl+Alt+t, а там просто вводим sudo gparted, ибо без прав админа не заработает. Причем эта программулина доступна только в LiveCD. Если мы захотим заюзать ее в свежеустановленной убунте, нам надо будет ее предварительно установить.
В качестве заметки на полях: то, что нам попалась UEFI, можно увидеть по некоторым маркерам, типа при загрузке убунту с LiveCD мы видим не фиолетовый экран, а что-нибудь необычное. Я так понимаю, черный экранчик - один из вариантов. Картинку стянула из Интернетов:


3. В gparted мы смотрим, есть ли раздел ESP. (Есичо, его основные признаки: он в fat32, ну, или каком-нибудь другом fat, расположен одним из первых, имеет размер 100-200 мб, флаг может быть boot, hidden).
Вот например, как на этой картинке, честно стыренной из Инетренетов:



Здесь у нас в разделе "File system" все разделы отформатированы в ntfs, кроме того самого ESP, который в fat32.
На диске уже есть восьмая винда - это диск С: - это мы узнали из метки диска (столбец "Label"). Ну, и кроме всего на диске еще куча служебных разделов винды, об этом можно узнать не только по меткам  (WINRE_DRV и LRS_ESP), но и по флагам (столбец «Flags»). Все эти разделы скрыты (флаг hidden).
 /dev/sda5 - диск D.

Итак, если таки есть этот ESP-раздел, то скорей всего все ок и винда установлена в режиме UEFI.
А вот если нет, то пичалька. Надо переустанавливать, шоб было кошерно.
Т.к. мне данные, которые были на винде, не были нужны, я все снесла. А если есть данные, надо сделать бэкап.


Потом нам необходимо сделать все в gpt. Для этого мы идем в менюшке в 'Device' (устройство) и выбираем в меню «Create Partition Table…» (Создать таблицу разделов…).
Читаем предупреждение и идем дальше.
Нас интересует в этом окошке пункт "Advanced". Там мы выбираем gpt.


Всё дисковое пространство станет серым. Щелкаем на нем ПКМ и создаем необходимые размеры. Первый из новых разделов — специальный раздел ESP, требуемый для работы UEFI. Поскольку он форматирован в неродной для Linux файловой системе, и кроме того, должен быть загрузочным, то расположить его надо в начале дискового пространства. 

Ему надо определить размер в поле  «New size (MiB)» (Новый размер в МиБ14)), а файловую систему — fat32.

Делала по этому ману.


Потом я оставила 100 GB под винду, остальное сделала неразмеченной областью.
Дальше установила винду.
Потом снова загрузилась с флешки с линуксом в LiveCD. Там опять выбрала gparted и дорзабила остальные разделы.
В итоге у меня получилось так: 
1. 500 МB для лоадера. Тот самый товарисч, в котором надо проследить, чтобы был свойство "использовать как" было выставлено "загрузочный раздел EFI".
2. 100 GB или 102400 МB винда. Ее ваще трогать не надо при установке линукса.
3. 20 GB или 20480 MB для самого линукса. Точка монтирования "/".
4. 100 GB или 102400 МB для домашней папки. Точка монтирования "/home"
5. 250 GB или 256000 MB для общей между линуксом и виндой, но уже не в ext4, a NTFS c точкой монтирования "/media/data".

Это я доделывала по этому ману.

Вот дальше и начались мои страдания.
Линукс написал, что все ок, что он отлично установился, но я перезагрузилась, а попала снова на винду.
Вот хрень, - подумала я. Посмотрела в gparted, линукс и правда там.

Потом были долгие разбирательства, почему в моем гребаном HP какой-то напрочь урезанный BIOS, почему там негде выбрать приоритет загрузки и все такое прочее.
Потом мне подсказали, что можно нажать на F9 и вызвать boot menu) Я его вызвала, но он был активен в течение одной сессии и после загрузки снова включалась винда.
Я зело расстроилась, когда на форуме HP увидела ответ, что низя навсегда изменить, чтобы грузилась линуха. Но я не сдалась, полезла гуглить дальше и нашла ман, где говорилось, как это сделать.
Там надо было всего-то зайти в BIOS - System configuration - UEFI boot order - OS boot Manager.
Там нажать "Enter", потом выбрать приоритет загрузки - винда или линукс.
Честно стыренная картинка с сайта, который мне сильно помог:


Вот, собсвтенно, и все)



Ага, а между этими всеми дейсвтиями было море танцев с бубном, начиная с того, что у меня не получалось восстановить загрузчик граб через boot-repair и всякое такое прочее)

А, ну, и для хистори прикреплю че меня смутило, когда гуглила, можно ли на постоянке шоб был загрузчик граб, шоб не надо было каждый раз менять приоритеты:




вторник, 22 мая 2018 г.

500 Mb - ntfs - for windows loader
500 Mb - in fat32, esp - for loader
20 Gb - linux
3Gb - Swap
100 Gb - home
100 Gb - windows.
250Gb  - NTFS, common for both OS






500 Mb - in fat32, esp - for loader
20 Gb - linux - 20480
3Gb - Swap - 3072
100 Gb - home - 102400
250Gb  - NTFS, common for both OS - 256000
free space

пятница, 18 мая 2018 г.

selenium, почему крашится валидный тест, js, js_inited, waitForExist

Как я поняла, на сервере тесты идут очень быстро и Гермиона не поспевает за их выполнением.
И в нашей ситуации кошерно делать так:
1. Сначала мы пишем релоад, загружаемся на нужной страничке.
2. Потом мы делаем waitForVisible какого-то элемента - это признак того, что страничка загрузилась.
3. Потом делаем waitForExist и прописываем элемент с jsской. Типа, jsка может позже подгрузиться.
Т.е. в особо важных местах мы ждем того, чтобы засуществовал (ыыы) элемент с js.

Выглядит это примерно так:



.waitForVisible('.products__items', 6000)
.then(() => {
}, (err) => {
    console.log(err);
    testResult = false})
.waitForExist('.ua_js_inited', 10000)
.then(() => {
}, (err) => {
    console.log(err)
})

Пример взят из мобильной версии discount.hermione.js, есичо)

пятница, 20 апреля 2018 г.

Выделить элемент, селениум

В общем, надо было выделить элемент, которых два одинаковых, надо было употребить :nth-child. Я так и сделала, но только к более вложенному тэгу. У меня ничего не прокатывало. Надо было подняться на уровень выше и обратиться к предыдущему тэгу, к его родителю. У меня было вот так:

.then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
.waitForVisible('.coupon-editor:nth-child(1) .radio__box:nth-child(2)')

А надо было так: 

.then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
.waitForVisible('.coupon-editor:nth-child(1) .radio:nth-child(2)')

Отута скрин, есичо.

среда, 11 апреля 2018 г.

Селениум, траблы, xpath, много одинаковых элементов, попапы отдельно

В общем, была трабла, когда этот элемент был в нескольких местах. Да, попапы, кстати, отдельно, а не в тех элементах, где они выскакивают.
Так вот попапы сложены отдельно, поэтому, когда обращалась к элементам, мне нужен был аж 8-й попап. Можно было обратиться и по тэгам, прописав цифру "8", но это не путь самурая. Ведь если сделать так, добавят еще один попап и все сломается.
Решили сделать описание по xpath.

Получился вот такой код:

.click('.//body/*[contains(@class,"popup_")][1]//*[contains(@class,"menu-item")][2]')
.then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
.waitForVisible('//body/*[contains(@class,"popup_")][1]', 1000, true)
.then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
.getText('.coupon-editor:nth-child(1) .form-field[data-name = "enabled"] .button__text')
.then(text => assert.isTrue(text === 'Выключен', 'False: ' + text+ ' != Выключен'), (err) => {
    conslole.log(err);
    testResult = false})


сделать полосатые таблички, гуглшит

Идем в Format -> alternating colors. Там уже выбираем нужные цвета. Тока снять чекбоксы, типа, хэдера и футера.

вторник, 10 апреля 2018 г.

Глобальные переменные, селениум, сравнить значение в одном теге со значением в другом теге.

let viewNameCode = '';
let codeName = '';
return this.browser    .url(this.browser.options.baseUrl + '/manage/promotion/coupons')
    .then(() => assert.isTrue(true), (err) => {
        console.log(err);
        testResult = false    })
    .waitForVisible('.icon_add_box')
    .then(result => {
        if (result) {
        } else testResult = false;
        assert.isTrue(result, 'False: .icon_add_box не виден')
    }, (err) => {
        console.log(err);
        testResult = false    })
    .click('.icon_add_box')
    .then(() => assert.isTrue(true),(err)=> {console.log(err); testResult = false})
    .waitForVisible('.coupon-editor:nth-child(1) .form-field[data-name = "code"]', 10000)
    .then(result => {
        if (result) {
        } else testResult = false;
        assert.isTrue(result, 'False: .coupon-editor:nth-child(1) .form-field[data-name = "code"] не виден')
    }, (err) => {
        console.log(err);
        testResult = false    })
    .click('.coupon-editor:nth-child(1) .form-field[data-name = "code"] .input__control')
    .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
    .keys('Grandy')
    .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
    .getValue('.coupon-editor:nth-child(1) .form-field[data-name = "code"] .input__control')
    .then(text => codeName = text, (err) => {
        console.log(err);
        testResult = false    })
    .getText('.coupon-editor:nth-child(1) .coupon-editor__view-name-code')
    .then(text => {viewNameCode = text; if (codeName === viewNameCode){}else {testResult = false; console.log(codeName+ ' != '+ viewNameCode)}}, (err) => {
        console.log(err);
        testResult = false    })



Стояла задача взять значение из одного тега и сравнить его со значением из другого тега.
1. Объявили глобальные переменные, чтобы запихнуть потом в них значения.
2. С помощью .getValue взяли значение, запихнули это значение в переменную.
3. То же самое со вторым элементом.
Но во втором слвучае мы сразу сравниваем потом. Т.е. пишем условие.
if (codeName === viewNameCode){}else {testResult = false; console.log(codeName+ ' != '+ viewNameCode)}
т.е. если они равны, ничего не происходит, все норм.
Если фолс, то в консоль выводится ошибка, что они не равны.

понедельник, 2 апреля 2018 г.

Вложенность, обработка вложенности, надо ставить паузы в Гермионе, траблы, разбор кода




Вот для удобства не скрин, а сам код:

.getText('.cart__calc-position_field_discount .price__val')
.then(discount =>{
    let regexp = /\s/; // пустые значения    discount = discount.replace('','').replace(',','.').replace(regexp,'');
    console.log("discount="+discount);
    this.browser.getText('.cart__calc-position:nth-child(1) .price__val')
        .then(summa => {
            summa = summa.replace('','').replace(',','.').replace(regexp,'');
            console.log( "summa="+summa);
            this.browser.getText('.cart__calc-position:nth-child(3) .price__val')
                .then(kupon => {
                    kupon = kupon.replace('','').replace(',','.').replace(regexp,'');
                    console.log( "kupon="+kupon);
                    this.browser.getText('.cart__calc-position:nth-child(5) .price__val')
                        .then(total => {
                            total = total.replace('','').replace(',','.').replace(regexp,'');
                            console.log( "total="+total);
                            console.log('***************1');
                            console.log(summa + ' - ' + kupon + ' - ' + discount + ' = ' + total);
                            console.log((summa - kupon - discount) == total);
                            if ((summa - kupon - discount).toFixed(2) - total <=0.01) {}
                            else { console.log(summa + ' - ' + kupon + ' - ' + discount + ' <> ' + total); testResult = false}
                        })
                },err => {console.log(err); testResult = false})
        },err => {console.log(err); testResult = false})
})
.pause(5000)



Итак, разбор Ленкиного тупняка.

Сначала я не могла сообразить, почему этот элемент находился в хидден состоянии.


Он у меня отображался вот так:




А отображался он так, Потому что у меня заказа было мало, на скидку не дотягивало.



А это прогрессивная скидка, которая зависит от суммы заказанного товара.

Т.е. если бы сумма товара, как в тесте, который я написала, была бы больше 5к, то скидка составляла бы 10 % и этот элемент не был бы хидден.

Второй мой фолт, почему тест не работал, это то, что Гермиона не обрабатывает вложенность. Она фейлит и бежит дальше. Так было и сейчас. Надо обязательно ставить паузу после вложенности.



Вот тут regexp ищет все пробелы. Вот эта вот хрень "/\s/" - это означает пустые значения.
Дальше мы заменяем рубли на ничто, запятую на точку, пустые места на ничто.

Для чего нам надо было убирать пустые места?
Пустые места мы убирали, чтобы число воспринималось как число.

Если больше тысячи, то оно было так: 3 000, т.е. с пробелом. А нам надо, шоб было число. Пришлось юзать регэксп.

Вывод в Селениуме этого куска кода вот такой:



Да, логика тут такая:











Т.е. у нас тут складывается купон и скидка.

Мы делаем:
сумма - купон - дисконт = тотал.
5145.80 - 10 - 514.58 = 4621.22

И если:

сумма - купон - дисконт  -  тотал <= 0.01 (1 коп, потому что почему-то с "0" не проходит тест)
5145.80 - 10 - 514.58 - 4621.22 <= 0.01, то норм

В противном случае

сумма - купон - дисконт не равно тоталу.
5145.80 - 10 - 514.58 != тоталу, мы сваливаемя с фолс.




четверг, 29 марта 2018 г.

Клик получает другой элемент, селениум

describe('Удаление товара:',function(){
     it('Гость', function () {
         let testResult = true;
         return this.browser             .reload()
             .url('/')
             .localStorage('POST',{key: 'subscribe-modal-visibled', value: 'true'})
             .localStorage('POST',{key: 'geo-popup', value: '{"isDetected":true}'})
             .localStorage('POST',{key: 'geo-link', value: '{"isDetected":true}'})
             .refresh()
             .waitForVisible('.envelopeIcon_3E', 10000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err)})
             .click('.icon_menu')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.main-menu__body>.nav>.nav__container>.nav-item:nth-child(7)>.nav-item__container>.icon_material')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .scroll('.main-menu__body>.nav>.nav__container>.nav-item:nth-child(7)>.nav-item__container svg')
             .click('.main-menu__body>.nav>.nav__container>.nav-item:nth-child(7)>.nav-item__container svg')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.nav-item_subnav:nth-child(7) .nav-item__subnav .nav__container .nav-item:nth-child(1)', 3000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .click('.nav-item_subnav:nth-child(7) .nav-item__subnav .nav__container .nav-item:nth-child(1)')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.recomms__head', 10000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err)})
             .waitForVisible('.products__items', 6000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .click('.products__items .product:nth-child(1) .product__cart button')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .click('.products__items .product:nth-child(2) .product__cart button')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .click('.products__items .product:nth-child(3) .product__cart button')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .click('.products__items .product:nth-child(4) .product__cart button')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.cart-button__popup', 3000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .getText('.cart-menu__counter')
             .then(text => assert.isTrue(text === '4','False: ' + text + '!= 4'),(err)=> {console.log(err); testResult = false})
             .click('.icon_shop_cart')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.cart-item', 5000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .elements('.cart-item')
             .then(result => assert.isTrue(result.value.length === 4, 'False: ' +result.value.length + '= .cart-item != 4'), (err)=> {console.log(err); testResult = false})
             .getValue('.cart__items .cart-item:nth-child(1) .cart-item__quantity .input__control')
             .then(value => assert.isTrue(value == 1, 'False: ' + value + ' =.cart__items .cart-item:nth-child(1) .cart-item__quantity .input__control != 1'),(err)=> {console.log(err); testResult = false})
             .doubleClick('.cart__items .cart-item:nth-child(1) .cart-item__quantity .input__control')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .keys('0')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForExist('.cart-item_deleted', 3000)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.cart-item_locked', 2000, true)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .elements('.cart-item:not(.cart-item_deleted)') // not deleted positions (those, that remained)             .then(result => assert.isTrue(result.value.length == 3, 'False: ' +result.value.length + '= .cart-item != 4'), (err)=> {console.log(err); testResult = false})
             .elements('.cart-item')
             .then(result => assert.isTrue(result.value.length == 4, 'False: ' +result.value.length + '= .cart-item != 4'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(1) .cart-item__image')
             .then(result => assert.isFalse(result, 'Картинка удаленного товара видна'), (err)=> {console.log(err); testResult = false})
             .getText('.cart-item:nth-child(1) .cart-item__deleted .cart-item__text')
             .then(text => assert.isTrue(text === 'Товар убран из корзины', 'Текст не соответствует "Товар убран из корзины"'), (err)=> {console.log(err); testResult = false})
             .getText('.cart-item:nth-child(1) .cart-item__deleted .button__text')
             .then(text => assert.isTrue(text === 'Вернуть','Текст не соответствует "Вернуть"'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(1) .cart-item__title')
             .then(result => assert.isTrue(result,'Название товара не видно'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(1) .cart-item__packing-info')
             .then(result => assert.isFalse(result,'Информация о цене и фасовке видна'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(1) .cart-item__actions')
             .then(result => assert.isFalse(result,'Кнопка "Убрать из корзины" видна'),(err)=> {console.log(err); testResult = false})
             .getValue('.cart__items .cart-item:nth-child(2) .cart-item__quantity .input__control')
             .then(value => assert.isTrue(value == 1,'Начальное значение количества товара2 не равно 1'), (err)=> {console.log(err); testResult = false})
             .click('.cart__items .cart-item:nth-child(3) .cart-item__actions .button')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .pause(500)
             .waitForVisible('.cart-item_locked', 1000, true)
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .elements('.cart-item:not(.cart-item_deleted)')
             .then(result => assert.isTrue(result.value.length == 2, 'Количество неудаленных товаров не равно 2'), (err)=> {console.log(err); testResult = false})
             .elements('.cart-item')
             .then(result => assert.isTrue(result.value.length == 4, 'Количество всех товаров не равно 4'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(3) .cart-item__image')
             .then(result => assert.isFalse(result, 'Картинка удаленного товара видна'), (err)=> {console.log(err); testResult = false})
             .getText('.cart-item:nth-child(3) .cart-item__deleted .cart-item__text')
             .then(text => assert.isTrue(text === 'Товар убран из корзины','Текст не соответствует "Товар убран из корзины"'),(err)=> {console.log(err); testResult = false})
             .getText('.cart-item:nth-child(3) .cart-item__deleted .button__text')
             .then(text => assert.isTrue(text === 'Вернуть','Текст не соответствует "Вернуть"'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(3) .cart-item__title')
             .then(result => assert.isTrue(result,'Название товара не видно'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(3) .cart-item__packing-info')
             .then(result => assert.isFalse(result,'Информация о цене и фасовке видна'), (err)=> {console.log(err); testResult = false})
             .isVisible('.cart__items .cart-item:nth-child(3) .cart-item__actions')
             .then(result => assert.isFalse(result,'Кнопка "Убрать из корзины" видна'), (err)=> {console.log(err); testResult = false})
             .click('.cart-item:nth-child(1) .cart-item__deleted .button__text') // кнопка вернуть             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .waitForVisible('.cart-item:nth-child(1) .icon_delete_forever')
             .then(() => assert.isTrue(true), (err)=> {console.log(err); testResult = false})
             .scroll('.cart-item:nth-child(3)')
             .click('.cart-item:nth-child(3) .cart-item__deleted .button__text')
             .then(() => assert.isTrue(true),(err)=> {console.log(err); testResult = false})
             .waitForVisible('.cart-item:nth-child(3) .icon_delete_forever')
             .then(() => assert.isTrue(true),(err)=> {console.log(err); testResult = false})
.then(()=> assert.isTrue(testResult))
});





Вот в этом участке была трабла. Почему-то вместо третьего элемента клик получала шапка.
Оно немного прыгало и клик получал другой элемент.
Когда мы прописали такой вариант: 

.scroll('.cart-item:nth-child(3) .cart-item__deleted .button__text')
.click('.cart-item:nth-child(3) .cart-item__deleted .button__text')

Он не сработал, надо было только .cart-item:nth-child(3)

Т.е. вот так: 

.scroll('.cart-item:nth-child(3)')

Потому что когда мы обращаемся конкретно к кнопке, она находится внизу, а надо ко всему блоку, к большому элементу в целом.