📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Playwright за 1 час: полный проект автотестов с нуля | Пример на Java и Python

БАГОИСКАТЕЛЬНИЦА1:08:41

Transcription

Привет. Если ты давно хотел разобраться с Playрай, но не знал, с чего начать, то это видео для тебя. Посмотри на этот проект. В нём написаны UI-тесты, используются Page Object Model, есть отчёты Ар, скриншоты припадений и понятна архитектура тестового фреймворка. А вот так выглядит итоговый алюпорт. И всё это мы получим в конце урока.

Итак, меня зовут Аня, и в этом видео я покажу не просто, как написать парутестов на Playрай, а как построить полноценный проект с нуля всего за одно видео, которое не стыдно будет показать на собеседовании или использовать как основу для реальной работы. За это время ты разберёшься, что такое Playрай и почему он стал таким популярным, как писать UI автотесты, как построить архитектуру тестового проекта, как использовать Page Object Model и как подключить арепор, чтобы делать скриншоты при падении тестов. Ну и бонусом, как хранить настройки проекта в конфигурационных файлах.

Всё это мы будем писать на Java, но если ты пишешь на Python, то тоже оставайся. В конце видео я покажу абсолютно аналогичный проект на Python, и ты увидишь, что отличий там совсем немного. Также я подготовила бесплатный практикум на степик с пятнадцатию практическими заданиями. После просмотра ты сможешь закрепить знания на практике и самостоятельно реализовать дополнительный тестовый сценарий. Ссылка будет в описании.

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

Итак, быстренько расскажу, что такое Playri и зачем он нужен. Playri - это инструмент от Microsoft для автоматизированного тестирования веб-приложений. Если по-простому ты пишешь код, который открывает браузер, кликает на кнопки и проверяет, что всё работает, и один и тот же тест запускается и в Chrome, и Firefox, и Safari без изменений. Из ключевых преимуществ он быстрый, потому что тесты идут параллельно. Также он надёжный, сам ждёт, пока элементы появятся на странице без лишних пауз в коде. И плюсы из коробки: скриншоты, видеозапись и умные локаторы.

Теперь разберёмся раз и навсегда, почему я выбрала Playрай, а не Селениум. Селениум - это старый стандарт, и у него есть проблемы, которых в двадцать шестом году уже не хочется терпеть. Первое - это ждание элементов. Селениум ты сам пишешь. Подожди секунду две. В Playрай это встроено автоматически. Второе - установка. Селениум требует отдельно скачивать драйвер, настроить под себя версию браузера в playрай одна команда и всё готово. Третье. Параллельность и отчёты. Вселению нужны отдельные инструменты. В PlayRй - это часть фреймворка. Итог простой. Playriрай экономит время на настройку и даёт стабильные тесты.

Далее я просвещу, зачем нужны все эти инструменты вместе с PlayR. Play отвечает за то, как написаны тесты, но нужно ещё понять, как их запускать и как видеть результаты. И тут подключается Git 5 и Alure. Git 5 - это фреймворк, который организует тесты, группирует их по классам, позволяет запускать код до и после каждого теста и запускает всё это параллельно. Думай об этом как о планировщике. Арепорт - это отчёты. После прогона тестов ты открываешь дашборд. Сколько прошло, сколько упало, где конкретно сломалось, со скриншотами и шагами. Это удобно как тебе, так и команде, которая не пишет код. Схема простая: playрай пишет тесты, Gют их запускает, а показывает результат. Запомнили?

Теперь идём к практике. Открываем Intel ID и создаём проект через New Project. Называем наш проект. Я назову его в честь плейрайта. А назовём ещё также Framework Java. Ура! Мы создали проект. Теперь мы будем редактировать файлик по XML. А сейчас произойдёт магия. Я сейчас копипастом ставлю все настройки и библиотеки импортируемые. А, но сейчас больше расскажу, зачем это всё нужно и что мы используем. А в Properties я прописала все переменные для того, чтобы их было удобно потом редактировать, увеличивать версии. Это чисто для удобства. Вот здесь, например, можно увидеть в теге version. А здесь вот как раз эта переменная playrite version. Вот здесь она у нас и есть. и записано. Тут только чисто для удобства.

Итак, какие же у нас есть а зависимости? У нас есть Playri, далее ПИТ, э несколько версий тут API, Engine, Params и J Unit 5, а Alure у нас как раз-таки и Alure Attachment. Это как раз про то, чтобы сделать скриншоты. А далее я добавила ещё плагины. Это Maven Plugin. А всё это тоже для того, чтобы скриншоты делать. Всё это, чтобы записывалось в папочку Alure Results, то есть вот это всё, это для этого и нужно. Через вот кнопочку можно будет обновить все библиотеки, и они автоматически скачаются.

Где же я всё всю эту информацию брала? Все актуальные версии библиотек я беру на сайте MVN Repпозиitory. Через поиск я вписываю интересующую меня библиотеку, а ищу и выбираю библиотеку, где больше всего использований. А далее продвигаюсь вниз и беру последнюю версию. А также вот здесь можно всё это скопировать и перенести себе в проект. Всё просто. Также не забываем про правую панельку от Мейвона, где мы можем как раз-таки а очистить все наши зависимости и заново установить. То есть командой мы как раз-таки убираем все зависимости и временные файлы. Через install мы всё заново скачиваем и собираем проект.

Теперь займёмся конфигурацией проекта. Закрываем Mayon и переходим к папке тест. Здесь мы создадим аналогичную папку resources. Вот такпаст можно попробовать сделать. А далее здесь создадим файлик pro Properties. Добавим сюда конфигурацию. Здесь у нас base URL - это сайт, с которым мы будем сегодня работать. Потом у нас есть тут логины и пароли для юзера. А также настройки для браузера. Heitless - это значит, что у нас тесты будут выполняться в фоновом режиме. Также браузер type - это Chromeum, ну, то есть Chrome браузер и браузер 30.000 - это 30 секунд. Означает, что браузер будет ждать отклика какого-нибудь элемента.

Теперь создадим конфигурационный класс, который будет как раз работать с этими переменными. В папочке Java мы создадим пакет Config. И в этом пакете создадим класс Config. В этом классе я уже подготовила код. А здесь в целом всё просто. А этот код как раз связывается с файликом Properties, в котором хранятся какие-то вот переменные. А вообще зачем, ну, нужен вот этот протис? Почему нельзя прямоком в коде использовать? Во-первых, можно часто переиспользовать одни и те же переменные. И если мы будем что-то менять, то мы поменяли в одном месте и всё, и больше нигде не нужно менять. Это первый плюс. Второй плюс, а в таких тест properties могут храниться какие-то секретные данные, то есть какие-то секретные логины, пароли, которые не должны нигде светиться в коде. И поэтому мы используем вот такую конфигурацию. Здесь в целом в коде всё просто. Аа здесь мы говорим, что вот здесь найди нам этот файл, подключись к нему и далее уже используем методы. То есть мы можем потом напрямую вызывать в этом классе config метод, например, без base URL, а далее там get user э там пароль и так далее. То есть всё в одном месте. Мы так вызываем, так получаем и дальше работаем.

Теперь мы создадим общего родителя для всех тестов. В папке Java мы создаём пакет Base. Далее в этом пакете создаём класс. Называется он base сейчас будет небольшая магия. Я вставлю снова код заранее подготовленный для того, чтобы мы не теряли время на его написание. А для чего вообще этот абстрактный класс? Если мы не будем его использовать, то тогда этот код будет постоянно дублироваться в нашивых тестовых классах. Представим, если у нас, например, их 20, 30, 40, 50 этих тестовых классов и а получается, в каждом классе нам придётся вставлять вот этот вот код для того, чтобы хоть как-то запустить наш браузер. Э согласитесь, это неудобно. Э, и если нам нужно будет что-то поменять, это нужно будет делать во всех там, ну, 20-трицати классах. И это ужасно неудобно. Поэтому мы вынесли всё в отдельный класс, а, от которого потом наши тестовые классы будут наследоваться.

Теперь я объясню содержимое этого класса. А у нас здесь есть метод с аннотацией before each. Что это значит? Это значит, что перед каждым тестом ты должен запускать метод. а, который как раз-таки выполняет какие-то конкретные действия. А что у нас здесь происходит? У нас здесь создаётся объект play. Далее уже опции. Здесь мы подключили как раз-таки наш ранее созданный тест config с методом из HeL. Это значит, что мы будем а гонять тесты а фоново. То есть, если мы, э, углубимся, мы как раз возвратимся в наш тестовый класс и увидим, что уже подсвечивается голубеньким, что мы, а, как раз где-то уже используем. А вот далее как раз-таки устанавливаем браузер, какой мы хотим. Опять же из тестового класса Конфига. Здесь у нас там это три варианта есть. А далее, э, мы устанавливаем размеры окна, то есть это 1.280 пикселей на 720 пикселей. А здесь мы как раз-таки устанавливаем тайт тоже из нашего конфигурационного класса и создаём страничку.

Далее у нас идёт следующий метод с аннотацией after each. Что это значит? Это значит, что мы после каждого действия вызываем этот метод и с определёнными действиями. Что же этот метод делает? Он сначала закрывает страничку, потом а закрывает браузер и закрывает уже playрай, то есть освобождает ресурсы. А нужно сделать именно только в этом порядке, потому что если мы сначала закроем Playрай, то у нас уже посыпалятся ошибки, потому что страничка у нас не найдена или там браузер не существует. В общем, именно нужно в таком порядке. Ну, ещё дополнительно я добавила метод, который мы будем постоянно юзать - это а метод, который будет открывать главную страницу сайта. А всё просто, будем его использовать в тестах, и он будет всё в одном месте, что опять же очень удобно. и устраняет дублирование кода.

Также мне не очень здесь нравится в отображение в папочках, и я думаю, лучше это всё-таки убрать, чтобы не как бы не засоряло нам а всю эту информацию. То есть вот это вот всё, она не очень красиво выглядит. А когда у нас будет больше файлов, будет больше информации, и это нам только будет мешать. Поэтому через три точки я возьму и уберу галочку members. Всё отлично. Теперь у нас всё симпатично, а, и можно дальше работать.

Ну и последняя настройка. Она будет как раз-таки относиться к Алюру. В папочке Resources мы создаём новый файлик. Он будет называться Alure Properties. Далее в нём мы как раз-таки поместим а наш нашу настройку. этой настройкой мы говорим Алю, что смотри, вот давай в папке Target и в папке AL заs а ты будешь складывать все свои результаты работы, а благодаря которым мы потом сможем запустить, а алры отчёт и посмотреть всю информацию про тесты.

Плюсом нам нужно добавить конфигурацию для работы с со скриншотами. А в папочке Java создадим пакет, создадим в нём класс Screenshot on failure. Я опять применяю магию, вставляю уже готовый код. Итак, вообще, зачем нам нужен этот класс? Наш класс имплементируется от расширения Gunnit ПГО. А это нужно для автоматического создания скриншота и прикрепления его к Алюру при падении теста. А вот этот вот вот эта переменная, она как раз-таки указывает на текущую нашу страницу. И дальше мы уже ээ используем метод, а, в котором описываем, как мы хотим всё это видеть. То есть вот у нас как должны прикреплять и всякие тонкие тоже настроечки. То есть самый небольшой класс, но делает большие вещи. Ещё один важный момент, так как у нас есть тут pageхохolder, его как раз мы ещё будем использовать. BAS test. Допишем здесь вот в коде и page, то есть установим нашу страничку текущую, а для того, чтобы делали скриншоты. Ну ещё дополнительно мы в методе Tear Down добавим а метод этот remove, который будет удалять нашу текущую страничку, а для того, чтобы все эти ресурсы очищались и всё работало корректно. Также не забудем поставить обязательную аннотацию, которая как раз-таки скажет классу base test: "Использую расширение скриншот он failor". Всё, мы закончили с нашей конфигурацией и перейдём к написанию автотестов.

Мы будем тестировать на сайте Souls Demo. Он в целом стабильный, почти не меняющийся, и поэтому тесты наши тоже будут стабильными. И в целом он очень простой для понимания. А здесь мы на страничке логин, и поэтому мы сейчас создадим а тест логинтест. Создаём в папке Java папочку tests. Здесь у нас будут храниться все тесты. А далее создаём наш класс тестов. Он будет называться а логинтест. Также я добавлю три аннотации, которые помогут нам а красиво отобразить результаты тестов в валютчёте. Это Epic Feature и Display Name. Напишем сначала нотацию Epic. То есть это что-то совсем общее. Можно назвать, например, Source Demo UI test, то есть совсем общее. Теперь создадим фича, то есть функциональность какая у нас. Назовём авторизация, то есть мы будем авторизовываться. Ну и добавим аннотацию display name, в котором пропишем, что это у нас тесты авторизации. Также не забываем наследоваться от нашего base test, ранее созданного, то есть через extends добавим тест base.

Дальше мы должны как-то работать страницей, и поэтому мы будем использовать page object model. А создадим в папке Java а другую папочку под названием Pages. Здесь у нас будут храниться все-все наши странички. и создадим страничку для класса тестов login test. Она будет у нас называться в целом аналогично через вот login page. Ещё пару слов скажу, зачем вообще нужны страницы. А тесты должны работать с каждой страницей. А, и для этого мы должны написать базовые методы взаимодействия с этой страницей для того, чтобы в тестах мы могли варьировать разные вообще случаи, тест-кейсы и варианты э развития событий. И поэтому нам нужны странички. Сейчас мы увидим, как это полезно и как это тоже, опять же, сокращает код нам. А, создадим переменную page, а она как раз, как можно увидеть, от плейрайта. А также создадим конструктор. Вот уже всё автоматически создалось. И теперь создадим наш метод, который будет взаимодействовать со страницей. А назовём его так вот. Public void, а enter username. Как мы помним, что там у нас есть логин. А вот сейчас мы и будем с помощью теста его вводить. Здесь у нас будет в аргументахusernrame для того, чтобы можно было разные логины вводить и проверять, а как у нас реагирует страничка. А дальше мы напишем ещё шаг через степ. Опять же, это для того, чтобы красиво отображалась валютчёте и мы понимали где у нас тест упал, на каком шаге и как нам нужно распознать что именно сломалось. А в степе мы как раз-таки напишем, а, ввести, то есть действие какое-то, да, ввести логин. Ставим как раз-таки вот этот наш фигурные скобочки. То есть это будет ещё и красиво отображаться, то есть вести логин и какой-то там логин. То есть мы уже э будем меньше тратить время на вот этот вот дебаг и выяснение причин, почему же что-то сломалось.

Дальше нам нужен локатор, который как раз-таки будет находить этот элемент на странице и делать какие-то над ним действия. Давайте посмотрим, как этот локатор выглядит. А вот у нас он здесь. Сейчас мы через посмотреть код найдём наш локатор и вообще как мы будем за ним следить. Вот здесь вот есть дататеestст username. Как раз-таки чаще всего в хороших компаниях и в хороших командах афн-разработчики добавляют вот этот вот атрибут дататест э для того, чтобы нам, тестировщикам, легче тестировалось, потому что иногда, например, очень длинные классы или вообще может быть не быть класса. И это иногда так, э, сложно, что приходится всякие придумать костыли, но благо на сайте есть дата-тест, и мы его как раз-таки будем использовать. Я его как раз-таки скопирую нам, а, и откроем наш проект. Мы напишем как раз-таки page. Вот то, что мы в начале записали. А pageка и вписываем наш локатор. То есть всё можно использовать эт локатор в наших тестах. Дальше мы что делаем? Мы хотим заполнить этот это поле заполнить значением usernрame. А для этого пишем fill и наш usernр вот этот вот. Всё, первое действие у нас готово.

Для полноценного теста я ещё добавлю метод, который вводит пароль. Этот мы скопируем, вставим. То есть он будет абсолютно аналогичным. Здесь мы только запишем пароль. Пароль мы не будем, так как это должно быть безопасно. Мы не должны секреты наши выдавать, но логины мы можем выдавать, а пароли - это уже всё, это уже секретная информация. Дальше мы здесь переименовываем метод, как enter password. Здесь мы тоже пишем password. Здесь также. И посмотрим, как у нас выглядит локатор на нашей страничке. Нажимаем на Passwвор и посмотреть код. Ага, здесь у нас тоже есть дататест и есть значение паспорт. Всё, мы его копируем и как раз будем сейчас использовать в коде. А вот так вот выделяем и вставляем. Всё, о'кей. Мы ввели логин, ввели пароль. А дальше что? Нам нужна же какая-то проверка. То есть, например, успешная авторизация. А для этого мы снова посмотрим на нашу страничку и увидим, что у нас ещё есть кнопка логин. И для неё мы тоже напишем метод, который будет кликать на эту кнопку. Заранее посмотрим вообще, что у нас из себя представляет кнопка. Здесь также есть дататеestст, а login button. Всё, копируем. Сейчас будем использовать а в новом методе. То есть создаём, а, так же, как и предыдущие методы public, клиck логин. Здесь у нас не будет аргументов, так как это обычное простое действие, и его даже не особо как-то описать в шаге, но мы обязательно добавим тоже шаг, а, и напишем, что нажать на кнопку логин. Всё просто, нажать на кнопку логин. Всё, что мы сделаем в этом методе, мы также сделаем page, дальше локатор, вставим тот самый локатор, который мы копировали, и берём метод. То есть у нас, если можно посмотреть, внизу очень много методов, но нас интересует просто клик. То есть берём, пишем, а, клик. И всё, по сути, э, мы написали уже аж три действия со страничкой.

Теперь мы идём, э, в наш класс тестов и будем использовать наш login page. Для этого создадим, а, переменную login page, а, которую мы импортируем. И дальше добавим мм метод, а, который будет выполнять какие-то действия перед каждым нашим тестом. А этот, э, нотация before each. А дальше у нас void open, то есть открывать эту страничку мы будем с помощью этого метода. А как мы можем помнить, что в base у нас есть а такой метод очень удобный, Open Base URL. А мы его как раз-таки будем тоже здесь использовать. То есть так как мы наследуемся, этот метод уже виден этой программе. А дальше мы объявим login page new login page и наша как раз таки страничка, которую мы где объявили в base.

Теперь пишем наш тест через аннотацию тест. Это аннотация от Gunit 5. А дальше будем писать display name, то есть говорим о том, что это за вообще тест. А я его назвала LG01 и с таким названием, то есть авторизация с валидным логином и паролем. То есть это наш первый тест-кейс, который мы будем реализовывать. Наш тест будет называться акful login. Как раз-таки берём наш login page и у нас же уже есть методы там. А мы как раз-таки будем, а, вот использовать enter username. А для того, чтобы не писать опять же вручную, а, постоянно везде одни и те же переменные, мы как раз-таки вынесли в тест config и будем это использовать. То есть берём этот класс testig и вызовем а метод get user. Так как у нас ещё будут другие тесткейсы с невалидным там логином и паролем, поэтому берём стандартного юзера. А что мы ещё делаем с этим с этой страничкой? Мы будем вводить пароль. Enter password. И здесь тоже самое get password. А, и, конечно же, кликать. А, кликлогин. Тут больше ничего не надо. Нам всё не нужно. Так. Опа. Всё копипастом сделали.

Ну что ж, попробуем запустить, посмотреть, как это всё отработает. Но, скорее всего, мы не увидим, так как всё будет запускаться в фоновом режиме. Так, тест у нас свалился. А, так, по причине того, что не может найти локатор. Мы немножко неправильно указали этот локатор. Сейчас я поправлю наш локатор. Это нужны ещё нам квадратные такие вот а скобки и должно всё заработать. То есть это обычно для всех таких локаторов. Ещё раз запускаем наш тест и смотрим, а как он проходит. Тест прошёл очень быстро, потому что опять же это плерай, он всегда у нас быстро-шустро работает. Но опять же можно сначала подумать о том, что, наверное, как-то не очень работает. Мы же не видим прямо вот как бы долгого процесса. А, но в целом мы можем удостовериться, что всё работает, потому что были бы ошибки. Но в конце мы ещё добавим этого теста проверку на то, что у нас открылась страничка вот эта inventory. Вот. Но просто для частоты эксперимента мы добавим сейчас ат сп. Опять же, его использовать не надо, это плохая практика. Это я покажу чисто вот для примера. А то есть будем ждать тут 3 секунды. Добавим у нас ещё сигнатуру. И здесь в 3 секунды подождём. Всё. В целом мы можем сейчас увидеть, а, даже по 2 секунды, чтобы не ждать очень долго, не задерживаться. Сейчас посмотрим, а как каждое действие выполняется. То есть вот сейчас запускается браузер. Вот он заполнил стандарт юзер. Теперь password. Теперь кликает на кнопку. Это не я кликаю, если что. Вот он открыл страничку и, ну, каталог товаров. Всё. А я это уберу. То есть я показала, что это в целом всё работает. Доверять этому тесту можно.

А теперь мы добавим действия о том, что мы открыли страничку Inventory Page, но у нас-то нет никакого а пейджа с этой страничкой, то есть придётся создавать. Вот. Но я сейчас покажу быстро, что это за страничка. То есть, если мы ведём, вот здесь как раз есть для нас тестовые логины и пароли, прямо здесь вот внизу футер. А вот у нас есть страничка Inventory, а здесь мы с ней тоже будем работать. Сейчас мы как раз-таки добавим её в наши тесты. То есть мы хотим убедиться, что мы действительно успешно залогинились, что мы не остались на этой страничке. То есть, если мы выйдем, тут совсем другой URL. То есть мы как бы, если мы можем якобы э войти успешно, а может быть сработать ошибка, и получается, мы не попали на страничку каталог товаров, и поэтому мы должны написать эту проверку.

Переходим в наш а проект, создаём страничку inventory page. Уventory page также будет похожа структура, как у login page. То есть мы тоже должны объявить переменную page, ээ, также конструктор и будем писать для него методы. Так, а попробуем таким образом. Только у нас здесь будет inventory page, то есть всё аналогично. Теперь добавим метод, который будет проверять, что мы находимся именно на этой страничке. То есть эта страничка inventory HTML. То есть, если посмотреть, а мы быстренько сейчас введём логин пароль. Вот она вот то, что страничка содержит вот вот этот вот URL. А, то есть здесь в целом всё просто. Мы используем метод Assert True от Gunit пятого, который как раз-таки берёт наш, его ссылку и проверяет, что эта ссылка содержит вот этот вот э наш экземпляр, кусочек вот этот вот. Будем использовать. Так, берём вот этот вот вот это название. Будем как раз-таки использовать inventory page. Потом inventory page равно new inventory page. Угу. А, и как раз будем использовать assert URL, наш новый созданный метод. Всё. То есть, по сути, это будет некая проверка, только можно, наверное, больше упростить. Вот создадим вот так. Таким образом. А, посмотрим, как наш тест работает. Так, а серт у нас не сработал. Почему же? А потому что у нас другой URL. Сейчас быстренько всё поменяем и всё будет чики-пуки. Так, запускаю наш тест. Всё сработало. Отлично.

Двигаемся дальше. Дальше напишем второй тест. Это у нас будет авторизация заблокированным пользователем. То есть мы должны проверить, что была у нас ошибка и никуда не пускает. А создаём также через тест. И название будет уже чуть-чуть другое. И название тесткейса, то есть это LG02, авторизация заблокированным пользователем. А метод теста также будет по-другому называться, то есть lock out user login. А и что мы будем дальше делать? Как мы видим, вообще у нас код-то повторяется, то есть уже два раза. А давайте всё вынесем в отдельный метод в login pйд, чтобы у нас всё было очень даже аккуратненько. А заходим в наш login page и создадим а отдельный метод. Так, создадим step будет называться, что просто как войти, как usернеam. Всё. То есть без детализации. Детализация у нас будет в предыдущих шагах. То есть всё это отобразится. Так, войти, как и наш, а, юзер, чтобы тоже всё красиво отображалось. Это будет видно валютчёте. Далее создаём а public void.

Также абсолютно аналогично. А, назовём это как логин.

Так, а, да, точно, у нас же используется как, а, user name и password. А дальше мы что используем? Мы используем этот метод, то есть просто enter username и наш username. Дальше Enter Password и наш Password. Всё просто. Ну и метод click. Всё отлично.

А, но так как мы работаем ещё и со страничкой каталога товаров, и так как мы используем модель Page Object, мы также будем возвращать в этом методе, а, нашу страничку Inventory Page, чтобы дальше с ней можно было тоже работать. То есть какая-то такая последовательность цепочек. А что это значит? Что мы будем возвращать а наш inventory page. Сейчас посмотрим, как это удобно выглядит. Это прямо очень удобно. То есть берём так и пишем New Inventory page. И как раз-таки наша наша страничка. Всё будем сейчас использовать в нашем тесте. А вместо вот этой всей как бы это полотна мы вот так вот будем вот так. Сейчас, а login page, а мы как раз-таки введём а-а логин и пароль. Всё, это мы стираем, это нам уже не нужно. Всё, в одну строчку уже всё превратилось, всё очень даже красиво. А можем даже вот так вот отступ сделать. Ну, это форматирование так, э просто кому как нравится.

А, ну и мы как раз можем добавить вот этот assert. То есть вот таким образом всё мы стираем. О, у нас очень красиво. То есть мы создаём login page, используем и всё. Вызываем метод такой-то и следующий метод. То есть мы, э, авторизовываемся и проверяем, что мы в ну в конкретном разделе сайта.

Вот здесь почти то же самое, только здесь мы не будем попадать на страницу каталога товаров, и поэтому чуть-чуть будет отличаться этот метод. А мы также его прямо копируем, а, но он будет уже по-другому выглядеть. То есть здесь мы назовём его как в степе попытаться войти с невалидными данными. То есть вот таким образом. А дальше назовём его как login expecting error. Также мы вводим логин, пароль кликаем. Но мы уже возвращаем нечку следующую каталога товаров успешную, а возвращаем саму же ээ самого же login page, то есть это будет return this, то есть возвращаем этот же класс, и это у нас будет login page. То есть вот таким способом это будет выглядеть.

Возвращаемся к нашим тестам. А, и вот вместо этого тоже полотна мы берём и используем вот этот вот метод. Так, сейчас также абсолютно сделаем. А через запятую также вот это вот скопируем красоту. Но нам же надо как-то проверить, что действительно мы не авторизовались, а мы попробуем получить как раз сообщение об ошибке. А, то есть, если посмотрим на сайт, то есть logout сделаем и вот как раз-таки вот он locked, да? Ээ, нет, давайте просто вот что-нибудь введём. А-а, также какой-нибудь там пароль непонятный. То есть, а, у нас авторизация с некорректным некорректным логином. Значит, мы пароль оставим валидный, а логин невалидный. Всё, попробуем логиниться. А у нас ошибка. Вот она ошибка. Epic Set Face. Вот мы как раз-таки будем проверять, появилась ли эта ошибка в нашем тесте. Это как раз, а, будет говорить о том, что мы остались на этой странице и у нас появилась ошибка.

Мы сейчас напишем ещё дополнительный метод, который как раз-таки будет проверять, что у нас есть эта ошибка. А, пишем step и назовём это как проверить, что отображается сообщение об ошибке. А мы здесь его вставим. А дальше напишем наш метод. будет тоже public, но уже void, потому что мы не хотим ничего возвращать, это уже конечная цель. Аа также напишем, что это у нас будет а error message. А, да, мы как раз будем ожидать, а, конкретную ошибку. Ой, так вот string ошибку и всё. А что мы здесь ожидаем? Будем писать assert. То есть воспользуемся методами get. А что же мы здесь хотим? узнать. Мы сейчас возьмём опять locator page locator и посмотрим, а где у нас этот locator. Так, посмо посмотреть код. Мм так у нас опять же есть data test error. Спасибо разработчикам. А и вот вот это сообщение. То есть а что мы возьмём? Мы возьмём вот этот вот selector data error. А его как раз-таки впишем, но не забываем про квадратные скобочки. Первый раз я его забыла, теперь не забываем. И есть метод is visible, а, который как раз-таки проверит, что у нас а эта ошибка отображается, что она вообще существует. Так, сейчас мы, возможно, скобочки неправильно поставили. А дальше что у нас? Помимо того, что мы действительно проверили, что у нас этот блок существует, надо проверить, как содержит ли он конкретное сообщение об ошибке. Пишем assert. А так у нас будет как раз-таки опять же этот locator, а вот здесь же и пишем, что м этот contains text, то есть содержит текст contains и тот самый текст мы и будем проверять. Вот здесь всё просто. Кстати, можно здесь заметить, что локаторы у нас дублируются, поэтому я рекомендую их вынести в конструктор класса, а это сократит дублирование и улучшит читаемость. Но если у нас единожды используется локатор, то выносить его нет смысла. Это всего лишь просто захломит наш конструктор, и это будет излишнее. Но так как у нас уже два раза повторяется, то это повод для вынесения. А создадим также переменную private final. Будет класс у нас locator. И назовём его error message. Его тоже нужно добавить конструктор. Вот. Но здесь мы будем не просто так делать, а именно равно page. И как раз, а вот то, что мы копировали, вот локатор. Всё это мы убираем, чтобы не мешало. Всё будем использовать таким образом в наших в наших методах. Вот всё. Красота. Теперь выглядит всё симпатичнее.

А теперь берём этот метод и возвращаемся к нашему тесту. Вот была цель авторизоваться заблокированным пользователем. Что же мы добавим? Мы добавим а вот этот вот assert тоже через точку, так как это у нас как целая цепочка выходит. А вот какая же нас будет ошибка? Ошибка вот она. Мы её прямо копируем. Вот. И возвращаемся к тесту. То есть вот такая ошибка. Всё отлично. Так, не забываем о том, что мы здесь авторизовываемся. заблокированным пользователем. А, стоп, мы же как раз-таки авторизовываемся стандартным пользователем, а, у нас автотест заблокирован, чуть-чуть перепутали, поэтому сейчас мы возвращаемся к ошибке и попробуем с заблокированным пользователем. То есть ошибка уже будет чуть-чуть другая. Вот, то есть пароль такой же. Вот уже ошибка другая. Поэтому мы вот эту будем использовать, чтобы у нас был конкретный правильный тест-кейс. А, то есть здесь ошибка чуть-чуть будет другая, но по сути этот блок ошибок он стандартный и он везде одинаков. А так здесь у нас будет не get standard, а get locked user. Всё, посмотрим, как у нас будет работать этот тест. Всё отлично. Можно было даже заметить, что у нас там немножко было видно, как ошибка высветилась. Значит, всё работает.

Теперь мы создадим тест-кейс, э-э, который будет авторизовываться с неверным паролем. Аа по сути, он будет абсолютно аналогичен, но с несколькими отличиями. А display name мы назовём по-другому, то есть будет называться вот так. А тест также будет называться таким образом. А, и у нас поменяется логин, то есть мы будем авторизовываться стандартным пользователем, да? То есть у нас же суть проверки - это авторизация с неверным паролем, а неверный пароль мы придумаем сами. То есть это же какой угодно. Можем написать вот а какой-нибудь password. Всё, всё просто. А сейчас посмотрим, какая должна ошибка высветиться. Но обычно, опять же, это в требованиях всё должно отображаться, и мы должны уже тестировать исходя из требований, что у нас всё на сайте, как выглядит. Но сейчас будет такая импровизация, будем сами смотреть, как у нас сайт выглядит. Но в целом он же как протестирован, а вот поэтому сейчас попробуем. Так, здесь у нас какой-нибудь другой пароль. Вот такой вот. Вот у нас как раз такая ошибка. Мы её и будем уже использовать. Можно посмотреть, что у нас уже этот метод есть, который проверяет на содержание этой ошибки и вообще, что она существует. Всё, у нас уже второй тест написан. Всё очень так просто, да, буквально несколько секунд. Опять запускаем. Смотрим, как у нас это всё выглядит. Ну, потрясающе. Уже третий тест работает.

Давайте ещё один тест забабахаем, который будет у нас уже четвёртый. Это вот такая вот авторизация с неверным логином, а, то есть уже и по-другому будет называться метод. А здесь у нас уже логин будет другой. А, то есть мы назовём, например, это вот таким образом. А, то есть неизвестный пользователь. Ну, а пароль можно стандартный взять, вот как здесь. То есть стандартный пароль. Вот. То есть всё в целом просто. Вот. Аэ. Ошибка будет одинаковая, но можем ещё раз убедиться. То есть логин у нас получается обычный, а а получается наоборот логин у нас странный будет какой-то, а пароль э стандартный. То есть ошибка одинаковая. Я нажимаю, ошибка одинаковая. Так что можем снова запустить следующий тест, четвёртый, и посмотреть, как всё отработает. Ура, мы закончили аж4 тесткейса.

А следующие тест-кейсы, которые тоже нужно бы автоматизировать, я оставила как домашнее задание для того, чтобы ты смог попрактиковаться. А это эти все домашние задания я разместила в моём бесплатном курсе на степике, поэтому переходи, смотри, практикуйся. Ссылка в описании.

Теперь мы будем писать тесты для странички каталога товаров. В папке мы создаём новый класс Inventory Test. А сделаем абсолютно так же, как из login test. И добавим три аннотации для allure отчёта. То есть, а мы сюда сразу же добавим вот таким образом. А здесь только отличается feature и display name. Feature у нас каталог товаров, display name- тесты каталога товаров. Сейчас я все аннотации импортирую в этом классе. Также не забываем наследоваться от Base test. И добавим также нашу страничку, которую, кстати, мы уже давно создали. Это у нас inventory page. А я его как раз тоже скопирую и добавлю в inventory test.

Теперь мы добавим метод, который будет выполняться до каждого теста с аннотацией before each. А что этот метод делает? Он, получается, открывает нашу страничку. Также он, а, заходит под определённым логином и паролем, и всё, можно теперь, э, что-нибудь тестировать на этой страничке. А сейчас мы этим займёмся.

Создадим наш первый тест. Тест у нас будет проверять, что на на странице каталога товаров отображаются все шесть товаров. А сейчас мы это импортируем, а, будем называть его info. А далее у нас должен быть здесь какой-то метод, который как раз-таки и будет это проверять. А метод мы создадим в нашем Inventory page. Перейдём в него. Сначала мы добавляем наш известный степ, а дальше название метода, а то есть будет вот таким образом он называться. И у него будет аргумент - это count. То есть метод будет по сути универсальным. можно будет проверить, там, не знаю, пять товаров будет отображаться, шесть, но у нас конкретно шесть. Как же это выглядит? А сейчас мы перейдём на наш сайт. И вот, э, мы уже остановились на нашей страничке Inventory. И можно увидеть, что всего шесть товаров, то есть 1 2 3 4 5 6. Всё отлично. Но как же мы это ещё будем проверять, что у нас шесть товаров? Нам нужно как раз-таки взять а какой-нибудь атрибут. Сейчас мы посмотрим код. И нам же нужно посчитать сколько этих блоков. У нас есть вот как раз-таки data test inventory item. Вот. И по сути их должно быть шесть штук. То есть что у нас будет за проверка? Также добавим assert. А вот как раз вот этот тот самый locator page locator. И таким образом а тоже через квадратные скобки. И у нас ещё есть встроенный метод, который как раз-таки посчитает, что у нас действительно столько, сколько нужно. Это метод has count. А, и добавим нашу эту переменную count, которую у нас в аргументах. Всё, по сути такая простая проверка. Возьмём этот метод и будем использовать в тесте. Не забудем добавить inventory page, что мы его используем. А что именно здесь нам нужно искать этот метод? Всё, по сути, тест у нас компактный, и сейчас мы его тоже запустим.

Следующий тест будет проверять, что каждый товар содержит название, описание, цену и кнопку add to card. А также абсолютно аналогично создаём аннотацию test, display name, а, описание и название метода. А так, сейчас немножко выровняем. А у нас будет проверка опять же проходить в нашем Inventory page. Переходим в него. У нас это будет шаг, что мы проверяем, что каждый товар содержит всю необходимую информацию. А далее, а как раз-таки и будем считать всё, что мы знаем. Как мы видим, что нам нужно использовать уже два раза вот этот локатор, поэтому вынесем его в конструктор. А также назовём аа как здесь же, то есть private, у нас будет это locator и будет называться inventory item. Всё, дальше сейчас мы импортируем, а, и будем вот здесь вот его использовать. То есть через а this inventory item. И вот этот вот ещё раз мы скопируем, а, через page locator. И вот вот такая штука. Всё. Дальше будем уже переиспользовать. То есть здесь мы уже это, а, убираем всё вот это вот. А и здесь мы уже как раз сможем и посчитать. Пишем int, то есть количество товаров. Пишем наш локатор и его количество count, да? То есть, возможно, может быть иногда в каких-то кейсах и больше. А далее, что же нам нужно проверить? Посмотрим на нашу страничку. То есть, э, у нас цель проверить, что каждый товар содержит название, описание, цену и кнопку. Всё это мы и будем проверять. Сейчас мы посмотрим, что именно вот этот блок должен быть виден. Возьмём наш data test и будем как раз-таки здесь это и проверять. Так как у нас шесть товаров, поэтому мы будем это проходить через циклы. Пишем int i = 0 и меньше как раз нашего количества count и и плюс плюс. Теперь пишем а locator item равно inventory item. И есть такой метод, как nth, то есть он по индексу как раз определяет, а, все наши товары. То есть, по сути, вот этот вот э локатор, он содержит в себе аж шесть одновременно товаров. Вот. Но мы же должны как-то проверить каждый товар, что он содержит, а, всю необходимую информацию. Поэтому будем это делать через цикл. А здесь у нас будет item и будем писать проверки. Также assert, дальше item locator. Так как локатор мы сейчас взяли имя товара названия, то это будет как locator и вот этот вот наш data test, который мы скопировали заранее. Далее нам же нужно ещё проверить, да, забыли ещё добавить, что у нас это как бы проверка is visible, то есть этот локатор видим. Теперь мы будем проверять описание. А, смотрим здесь через посмотреть код и видим, что у нас вот этот блок, а, содержит тоже data test. Берём его и копируем. И будем его как раз здесь же и использовать. Я предлагаю это всё дело скопировать, чтобы долго не писать. И, а, сюда мы вставляем. Всё, здесь всё абсолютно аналогично. Дальше то же самое делаем и с ценами. Смотрим этот блок. Это у нас блок, а, inventory item price. Тоже его берём и копируем. Так, эту проверку мы также копируем и вставляем в проверки. И остался последний элемент, который мы хотим проверить, что он действительно есть. А, переходим на наш сайт и вот посмотрим как раз-таки на нашу кнопку через посмотреть код. А я вижу, здесь есть побольше уже атрибутов, но опять же возьмём классический data test, а также его берём, а, вставляем здесь тоже копипаста. В целом, всё тут аналогично. Всё. Теперь предлагаю вызвать этот метод в нашем тесте и посмотреть, как этот тест поведёт себя. А также пишем inventory page. И вот этот наш самый метод будет вызываться. Запускаем этот тестик и смотрим, что у нас получилось. Хм, тест наш упал. Что же случилось? А, у нас он упал на втором элементе. То есть у нас цикл начинается с нуля. То есть первый элемент он нашёл, а второй элемент не нашёл. А так, то есть он по этому атрибуту не смог найти. Сейчас мы посмотрим, в чём же отличие. То есть вот посмотрим по этому атрибуту. Здесь у нас data test заканчивается на laps backpack. А здесь, здесь тоже очень важно. А здесь у нас Ага, вот BY заканчивается, то есть уже а этот атрибут отличается. Значит, попробуем взять атрибут через класс BTN inventory. Тогда я его скопирую и попробуем поискать уже с этим локатором. Значит, изменим вот этот вот локатор, поставим точку. Так как это у нас класс, мы таким образом обращаемся. А, и вот через это название попробуем ещё раз запустить тест и посмотреть, что получилось. Хм, тест прошёл быстро и всё без ошибок. Отлично. Значит, идём к следующему тесту.

Следующий тест-кейс - это, а, мы хотим проверить, что при клике на название товара открывается сама карточка товара. То есть вот мы открываем и у нас уже совсем другой дизайн. Аа будем как раз и писать тест. А с чего начнём? Начнём с того, чтобы написать аннотацию тест и display name с названием метода. А я сейчас быстренько вот так вставлю. А дальше что же мы будем делать? А мы как раз-таки создадим ещё дополнительный page, а который как раз и будет проверять, что мы действительно попали на эту страницу. Будет она называться, а, product detail page. Абсолютно так же, как и остальные странички. А мы создаём page и добавляем конструктор. А, открываем. Так, добавляем. И сейчас он скажет нам добавить конструктор. Всё отлично. Теперь пишем метод. Теперь мы добавляем проверку assert true. То есть мы как раз-таки сейчас будем проверять, что наш URL относится к URL детальной страницы. А берём наш, а, достаём из него URL, то есть текущий, и, а, говорим, что проверь, что наш URL содержит определённое слово или какое-то вот значение. А мы как раз-таки сейчас посмотрим. А вот у нас получается вот этот inventory item HTML через а вопрос вопросительный знак и ID равно. Вот это мы копируем, вставляем. То есть поэтому мы и будем искать. А дальше а уже добавим проверку assert. То есть этого недостаточно. Нам нужно понять, что у нас название карточки товара отображается. Поэтому тоже импортируем и пишем page опять locator. И уже нам нужно найти этот локатор. Сейчас мы посмотрим. То есть вот наш заголовок нашего товара. А, и здесь вот есть data test. Но я предлагаю ещё опять попробовать использовать а локатор для класса. То есть возьмём, скопируем именно вот это вот название класса. То есть такой у нас будет сейчас эксперимент. А также добавим через в кавычки точку. И вот таким образом скажем, что мы хотим искать элемент. А также через точку is visible. И в целом всё. Осталось вернуть нам новый объект для того, чтобы можно было бы дальше работать со страничками. Так, но здесь мы работаем дальше с inventory page, поэтому добавим дальше inventory page и page, то есть вот таким-то образом.

Теперь копируем название нашего метода, который мы будем использовать в тесте. А тут ещё один момент, что оказывается нам нужно ещё кликнуть на название товара. А это ещё дополнительный метод, но а так как мы всё ещё находимся в inventory page, поэтому здесь мы создадим ещё один новый метод. А будет вот он выглядеть таким образом, что кликнуть на название первого товара. А здесь у нас можно заметить, что вот этот вот локатор повторяется, то есть у нас уже есть название товара, и поэтому мы его вынесем в отдельный конструктор. А что мы делаем? Тоже также всё скопируем. То есть это у нас уже будет name. И здесь то же самое мы скопируем. То есть также мы это добавим вот таким образом. А мы берём это, копируем и вот сюда вставляем. Всё. Теперь мы можем переиспользовать и не писать такие длинные вещи, повторять. Вот так сюда и сюда. Всё, всё просто. То есть мы говорим, что кликни именно на первый товар, то есть first нам в этом поможет. И метод click. Всё. То есть здесь мы уже можно заметить возвращаем новую страничку, а, product detail page, то есть всё как и нужно. Поэтому берём этот метод, идём наш тест и будем его как раз сейчас использовать через inventory page. Берём этот метод click first item name. И дальше мы будем использовать наш assert, который мы ранее писали. Assert on detail page. Всё, у нас тест готов. Можем его запускать. Сейчас я для красоты вот так сделаю, чтобы было ещё более структурировано. Всё, запускаем этот тест. Всё отлично.

Идём дальше. Следующий тест у нас будет проверять сортировку, что товары отображаются по алфавитному порядку. То есть вот этот у нас есть фильтр, который как раз-таки сортирует товары а по названию и также по цене от большего к меньшему и от меньшего к большему. Нас сейчас пока интересует сортировка по названию, э, по алфавитному порядку. Ну что, начнём писать тест. будет он называться у нас таким образом. А дальше что нам нужно вообще сделать, а в этом тесте? А нам нужно сначала выбрать сортировку. Перейдём тогда на страничку inventory page, потому что сортировка относится именно к этой страничке. Создадим новый метод, а он будет называться select, а то есть выбирает сортировку. То есть это просто какое-то действие. А почему я ещё добавила option? То есть у нас же может быть несколько случаев, а которые мы тоже будем автоматизировать, поэтому это как раз-таки устранит дублирование кода. Так, дальше, что нам нужно? Нам нужно взять как раз локатор. Его сейчас мы найдём. Вот этот вот у нас элемент через посмотреть код. А так у нас есть здесь класс и data test. Можем использовать data test. А возьмём его и скопируем. Возьмём здесь. Будем его использовать. А, page, а, locator, как всегда, и вставляем с квадратными скобками наш локатор. Что мы дальше делаем с этим элементом? А, в playwright есть метод select option. Вот. И что же мы выбираем? Какой именно элемент? Мы выбираем как раз-таки просто пока абстрактный. То есть мы это укажем в самом тесте, какой мы хотим выбрать. То есть, если посмотреть опять же этот код, мы видим, а, что option у нас есть такой, такой, такой и такой. То есть четыре option. И как раз-таки можно будет сделать 4 теста. А, о'кей. Дальше берём этот метод, а, пишем, а, inventory page, а, вот этот метод select. И, а, как же он будет выбирать? Через option. Сейчас мы ещё раз посмотрим. Здесь есть значение value, да? И вот мы выберем как раз AZ, вот этот вот value. Возвращаемся к тесту и пишем эту опцию. Всё. То есть таким образом он должен выбрать именно вот такую сортировку. Дальше нам нужно как раз-таки получить а все наши товары, чтобы как раз-таки и понять, что действительно наши товары соблюдают ту самую сортировку. мы перейдём на нашу страничку inventory page и создадим ещё новый метод. А что же он будет делать? Он будет получать список всех названий товаров. А мы будем его создавать таким образом. То есть у нас уже есть name, то есть мы уже третий раз по ходу используем а этот локатор. И а у нас есть метод all text contents, то есть мы получаем список всех товаров. А так, поэтому берём, используем этот метод и будем использовать его в наших тестах. Значит, у нас он возвращает список, содержащую строку, то есть string. Таким образом, это у нас будет names равно inventory page. А, то есть вот этот как раз get item names мы получаем список. Вот. Но опять же, как же нам узнать, правильно ли он сортирует? А для этого мы возьмём, создадим отсортированный список. С помощью list мы пишем также название string, также sorted название нашего отсортированного списка. Также берём names, то есть мы берём же его и сортировываем, да? А так, ну, это уже будет новый список, то есть это уже у нас будет два разных списка. namesed будет отличаться, но по сути вообще не должно отличаться, потому что у нас по идее в правильном продукте всё должно работать хорошо, без багов. Поэтому мы сейчас как раз в этому и убедимся. Так, пишем через stream мы будем сортировать. Есть у нас такой метод sorted и to list. Всё, мы отсортировали. Вот. Но при этом, опять же, по сути вот этот вот список элементов, он не отсортирован. Ну и всё. Теперь последняя проверка. Через equals мы как раз-таки будем проверять. Берём наш вот этот вот списочек и а ожидаемый, то есть отсортированный. Они должны быть одинаковыми. Также бонусом я добавлю message, который будет говорить нам, что мы чего-то не сделали, потому что наш тест упал. То есть вот у нас такой message, то, то что товары должны быть сосортированы. Вот. Так что давайте проверять, как у нас работает этот тест. Всё отлично, у нас всё работает. Сортировка была проверена.

Далее мы будем писать уже аналогичный тест, который будет проверять сортировку по цене. Так, добавляем тест. А что этот тест будет проверять? Он будет проверять, что у нас сортировка от низких цен до высоких отображает товары по возрастанию цены. А, как мы знаем, что мы уже создали метод selectort, который как раз-таки выбирает нам нужную сортировку. А, но у нас уже сортировка немножко отличаться будет, поэтому переходим на сайт и видим, что у нас вот это вот от low to high, а именно называется low to high почему-то, но ничего. А, добавим сюда. А, и что будем делать дальше? А дальше нам нужно собрать все цены товаров. То есть до этого мы собирали название товаров, а теперь нам нужно собрать все цены и то же самое сделать. То есть мы должны это всё отсортировать. Так, значит, нам нужно создать новый метод в Inventory page, а, возле как раз selectр, то только уже это будет чуть-чуть отличаться метод. Он у нас будет собирать все а цены. Так, метод у нас будет таким образом называться. С таким шагом. Что дальше мы делаем? Мы берём локатор прайса, то есть, э, уже этот локатор используется, поэтому для того, чтобы не дублировать код, мы его вынесем отсюда. Так что таким образом берём и выносим сюда. Также у нас создаётся private locator price. Всё, здесь тоже самое. This price равно и наш локатор. Всё, теперь будем использовать здесь же. А что у нас будет метод делать? Он как раз-таки, а, берёт, получает всё содержимое, то есть all text contents, и через стримы мы будем мапить наши цены. Почему через map? А потому что цены у нас не простые, а с долларом. А у нас как бы Java не умеет сравнивать значение с долларом, поэтому нам нужно как раз-таки значение double выцепить и уже его и сортировать. Поэтому что мы делаем? Мы в мапе пишем: "Спарси мне, а, моё значение цены и при этом как раз-таки замени знак доллара на пустую строку". Всё. То есть мы по сути справились с этой задачей. А ещё добавим, конечно же, не забываем. Всё, теперь точно мы закончили. Ну и нужно вернуть весь этот список, поэтому мы это сделаем через return. Вот таким образом. Всё, можно идти получать, а все наши цены. Идём в Inventory Page. А мы уже как раз-таки а взяли вот эту сортировку. Теперь будем и проверять. А также создаём у нас list будет только уже double. Также мы назовём prices а равно inventory page и get item prices. Всё, мы как раз получили все текущие цены. И здесь всё аналогично, как с предыдущим методом. Мы берём также отсортировываем товары наши, а только уже по цене. То есть берём prices, также сортируем. И таким же образом мы проверяем, что действительно у нас всё о'кей. Тут мы заменяем на double, не забываем. Берём наш, а, prices и всё. То есть товары должны быть отсортированы, а, по цене и вот таким-то образом. Сейчас проверим, насколько наш тест правдив и работает. Ура! Все запланированные тесты для этого класса мы уже автоматизировали.

Оставшиеся тесткейсы для автоматизации я оставила на своём бесплатном курсе на степике для того, чтобы ты мог попрактиковаться. Чтобы не перегружать видео и уложиться в формат, я разобрала только часть заданий. Остальные тесты я добавила в GitHub. Там вы найдёте больше практики и сможете закрепить материал самостоятельно.

Также хочу показать, как выглядит Allure отчёт. Чтобы вы увидели скриншот о падении в тесте, я сломаю один тест таким образом. Добавлю здесь единичку. А, так что этот тест точно упадёт. Теперь запустим все тесты. Так, один тест у нас упал по тайм-ауту. Я его ещё раз перепройду, чтобы был более честный отчёт. Такое бывает, что на сайте падают тесты по тайм-ауту. Да, всё, тест прошёл. Всё, можем смотреть наш Allure отчёт. А через Maven можем увидеть вкладке в Plugins Allure Surf. Вот его и запускаем. Вот таким образом выглядит отчёт, то есть полная сводка и все возможные дашборды. А зайдём сюс. Вот здесь у нас отображены все шаги, где можно как раз-таки посмотреть, где что используется. А вот наш упавший тест. А здесь как раз показана ошибка, то есть что ожидалось и что пришло. И можно увидеть скриншот о падении. То есть вот таким образом а всё это отображается. Дальше остальные тесты каталога товаров. А здесь тоже всё по шагам расписано. Тесты корзины. Тут ещё больше шагов выходит. И тест оформления заказа тоже здесь всё расписано. И чем мы заполняли, какими данными всё написано. Вот и всё.

И как обещала, покажу вам проект на Python. Здесь у нас такая же структура, как и в Java версии. Есть настройки для всех тестов, те же тестовые сценарии и page objects. Плюс отдельно вынесены конфиги и файл test properties, чтобы удобно управлять окружением и параметрами запуска.

Если ты досмотрел видео до этого момента, то я поздравляю. За это время мы написали не просто несколько тестов, а собрали полноценный UI фреймворк на Playwright с правильной архитектурой, с allure отчётами, с page object, с конфигурацией проекта и автоматическими проверками. Это уже хорошая база, которую можно использовать для собственных проектов, тестовых заданий и подготовки к собеседованиям. Но самое важное - это закрепить знания на практике. Поэтому обязательно переходи в мой бесплатный практикум на степик. Там тебя ждёт 15 заданий разного уровня сложности, которые помогут ещё лучше разобраться в Playwright и научиться самостоятельно проектировать автотесты. Ссылка на курс находится в описании. Также в описании ты найдёшь ссылки на GitHub с готовым проектом на Java и Python. В репозитории есть весь код из видео, инструкции по запуску и readme с полезной информацией. Если видео оказалось полезным, то ставь лайк и подписывайся на канал. Это поможет мне выпускать больше материалов про тестирование и автоматизацию. И обязательно заглядывай в мой Telegram-канал. Там я регулярно публикую полезные материалы для тестировщиков. Спасибо за просмотр и до встречи в следующих видео. Пока-пока. M.