kipascriber v1.4.0
Kipascriber
Kipascriber - это инструмент, позволяющий генерировать функциональные тесты для фреймворка Cypress из тест-кейсов на русском языке.
Быстрый старт
Для того чтобы сгенерировать код автоматического теста на Cypress необходимо создать файл с расширением .suite.txt, имеющий следующую структуру:
Объекты:
TodoList: .todo-list li // задач|задачи|задача
TodoInput: [data-test=new-todo] // поле ввода
Состояния:
Completed: completed // завершена
Тест-сьют:
TODO приложение
Перед каждым тестом:
Шаг 1 - Перейти на https://example.cypress.io/todo
Тест:
Добавление новых задач
Шаг 2 - В поле ввода ввести "Feed the cat{enter}"
Шаг 3 - Проверить, что задач 3 штуки
Шаг 4 - Проверить, что последняя задача имеет текст "Feed the cat"
Тест:
Отметка задачи выполненной
Шаг 2 - Отметить чекбокс первой задачи
Шаг 3 - Проверить, что первая задача завершена
Затем нужно выполнить команду:
npx kipascriber
После чего в той же директории, где находился сьют-файл будут созданы два файла:
- .spec.js - файл с кодом автоматических тестов из сьюта
import { PageObject, StateClass, Endpoint, Text } from 'todo.data'
describe('TODO приложение', () => {
beforeEach(() => {
cy.log(`Шаг 1 - Перейти на https://example.cypress.io/todo`)
cy.visit(Endpoint.HttpsExampleCypressIoTodo)
})
it('Добавление новых задач', () => {
cy.log(`Шаг 2 - В поле ввода ввести "Feed the cat{enter}"`)
cy.get(PageObject.TodoInput)
.type(Text.FeedTheCatEnter)
cy.log(`Шаг 3 - Проверить, что задач 3 штуки`)
cy.get(PageObject.TodoList)
.should('have.length', 3)
cy.log(`Шаг 4 - Проверить, что последняя задача имеет текст "Feed the cat"`)
cy.get(PageObject.TodoList)
.last()
.should('have.text', Text.FeedTheCat)
})
it('Отметка задачи выполненной', () => {
cy.log(`Шаг 2 - Отметить чекбокс первой задачи`)
cy.get(PageObject.TodoList)
.first()
.check()
cy.log(`Шаг 3 - Проверить, что первая задача завершена`)
cy.get(PageObject.TodoList)
.first()
.should('have.class', StateClass.Completed)
})
})
- .data.js - файл с конфигурационными объектами для созданных тестов
export const PageObject = {
TodoList: '.todo-list li', // задач|задачи|задача
TodoInput: '[data-test=new-todo]', // поле ввода
}
export const StateClass = {
Completed: 'completed', // завершена
}
export const Endpoint = {
HttpsExampleCypressIoTodo: 'https://example.cypress.io/todo',
}
export const Text = {
FeedTheCatEnter: 'Feed the cat{enter}',
FeedTheCat: 'Feed the cat',
}
Полученный spec-файл является готовым автоматическим тестом на Cypress.
Правила написания .suite.txt файлов
Общие принципы
- В проекте может быть неограниченное количество suite.txt файлов. При запуске kipascriber будет осуществлена генерация кода автотестов для каждого из spec.txt файлов в проекте.
- Наличие в suite.txt каждого из разделов обязательно. Если для тестов не нужны объекты, состояния или предварительные действия, то содержимое раздела оставляется пустым.
- Разделы отделяются друг от друга пустой строкой.
- Порядок разделов фиксирован. При необходимости заголовок раздела может быть изменён (например, "Объекты:" на "Элементы страницы:").
Раздел "Объекты"
- Каждая строка раздела описывает один объект на странице. Может быть указано любое количество объектов.
- Строка начинается с идентификатора (названия переменной) для объекта. Рекомендуется использовать PascalCase нотацию. Название должно быть валидным идентификатором для JavaScript. Может быть указано любое название, однако рекомендуется использовать осознанное словосочетание, описывающее элемент.
- Идентификатор отделяется от остальной части символом ":" и пробелом. После идентификатора указывается локатор объекта. В качестве локатора может выступать любой валидный XPath.
- После локатора указываются ключевые слова, упоминание которых сигнализирует о необходимости использования данного объекта в коде автотеста. Ключевые слова отделяются от локатора двойным слэшем и пробелом.
- Для объекта может быть указано любое количество ключевых слов. Ключевые слова отделяются друг от друга символом "|".
Раздел "Состояния"
- Каждая строка раздела описывает CSS-класс, характеризующий состояние объекта. Может быть указано любое количество классов.
- Строка начинается с идентификатора (названия переменной) для состояния. Рекомендуется использовать PascalCase нотацию. Название должно быть валидным идентификатором для JavaScript. Может быть указано любое название, однако рекомендуется использовать осознанное словосочетание, описывающее состояние.
- Идентификатор отделяется от остальной части символом ":" и пробелом. После идентификатора указывается CSS-класс.
- После CSS-класса указываются ключевые слова, упоминание которых сигнализирует о необходимости проверки данного состояния в коде автотеста. Ключевые слова отделяются от CSS-класса двойным слэшем и пробелом.
- Для состояния может быть указано любое количество ключевых слов. Ключевые слова отделяются друг от друга символом "|".
Раздел "Тест-сьют"
- Содержит одну строку: название, которое будет указано в describe-блоке кода.
- При попытке добавить несколько строк они все будут добавлены в заголовок describe-блока, но рекомендуется оставлять название в одной строке.
Раздел "Перед каждым тестом"
- Для раздела справедливы те же замечания, что для разделов "Тест", за исключением наличия строчки - названия теста.
- В данном разделе указываются предварительные шаги, которые будут выполняться перед каждым тестом из последующих разделов. Например, здесь может осуществляться переход на нужную страницу, авторизация в системе и т.п.
Разделы "Тест"
- В одном входном файле тест-сьюта может быть несколько разделов "Тест", из каждого будет сгенерирован свой тест в рамках одного тест-сьюта.
- Первая строчка после объявления раздела - название теста.
- Каждая из последующих строк раздела описывает шаг теста. Может быть указано любое количество шагов.
- Каждый шаг состоит из двух частей: комментарий и действие, на основе которого будет сгенерирован код. Комментарий отделяется от действия первым встреченным символом "-".
- Комментарий служит для ориентирования в описании теста и не влияет на генерируемый код. В примере из "Быстрого старта" комментарием является указание шага ("Шаг N").
- Для каждого шага из раздела на основе действия генерируется соответствующий код. Примеры описания действий указаны в таблице доступных действий (ниже).
Таблица доступных действий
Действия, для которых может быть сгенерирован код делится на 2 категории:
Навигация между страницами и глобальная прокрутка страницы
Действие | Пример входного описания | Пример выходного кода |
---|---|---|
Переход на страницу | Перейти на https://example.cypress.io/todo | cy.visit(Endpoint.HttpsExampleCypressIoTodo) |
Прокрутка страницы (наверх, вниз, влево, вправо, в центр) | Пролистать страницу вниз | cy.scrollTo('bottom') |
Указание элемента и выполнение действия над ним
Из описания шага должно быть понятно и какой выбрать элемент, и какое действие (проверку) необходимо выполнить.
1. Выбор элемента (пример: требуется кликнуть на разные элементы. Замечание: допустимо использование различных предлогов)
Действие | Пример входного описания | Пример выходного кода |
---|---|---|
Выбор элемента по ключевому слову из PageObject | Кликнуть по задаче | cy.get(PageObject.TodoList).click() |
Выбор элемента по содержимому тексту | Кликнуть элемент с текстом "Click me!" | cy.contains(Text.ClickMe).click() |
Выбор чекбокса | Кликнуть по чекбоксу | cy.find('type="checkbox"').click() |
Выбор радиокнопки | Кликнуть радиокнопку | cy.find('type="radio"').click() |
Выбор поля ввода | Кликнуть на текстовое поле | cy.find('type="text"').click() |
Для выбора элемента также доступны модификаторы (пример: выбор элемента относительно чекбокса):
Действие | Пример входного описания | Пример выходного кода |
---|---|---|
Выбор первого элемента | Кликнуть на первый чекбокс | cy.find('type="checkbox"').first().click() |
Выбор последнего элемента | Кликнуть на последний чекбокс | cy.find('type="checkbox"').last().click() |
Выбор элемента перед указанным | Кликнуть на элемент перед чекбоксом | cy.find('type="checkbox"').prev().click() |
Выбор элемента после указанного | Кликнуть на элемент после чекбокса | cy.find('type="checkbox"').next().click() |
2. Действия над элементом - проверки
Описание для любой проверки должно начинаться со слова "Проверить". Для каждой из проверок существует обратный вариант, используемый с помощью добавления частицы "не".
Действие | Пример входного описания | Пример выходного кода |
---|---|---|
Проверка состояния по CSS-классу из StateClass | Проверить, что задача завершенаПроверить, что задача не завершена | cy.get(PageObject.TodoList).should('have.class', StateClass.Completed)cy.get(PageObject.TodoList).should('not.have.class', StateClass.Completed) |
Проверка цвета (CSS-атрибута color) | Проверить, что элемент с текстом "Hello" цвета #CCCCCCПроверить, что элемент с текстом "Hello" не цвета orange | cy.contains(Text.Hello).should('have.attr', 'style', 'color: #CCCCCC;')cy.contains(Text.Hello).should('not.have.attr', 'style', 'color: orange;') |
Проверка значения | Проверить, что поле ввода содержит значение "Hello"Проверить, что поле ввода содержит не значение "Hello" | cy.get(PageObject.TodoInput).should('have.value', Text.Hello)cy.get(PageObject.TodoInput).should('not.have.value', Text.Hello) |
Проверка текста | Проверить, что поле ввода содержит текст "Hello"Проверить, что поле ввода содержит не текст "Hello" | cy.get(PageObject.TodoInput).should('have.text', Text.Hello)cy.get(PageObject.TodoInput).should('not.have.text', Text.Hello) |
Проверка количества элементов | Проверить, что задач 3 штукиПроверить, что задач не 1 штука | cy.get(PageObject.TodoList).should('have.length', 3)cy.get(PageObject.TodoList).should('not.have.length', 1) |
Проверка отмечен ли элемент (например, чекбокс) | Проверить, что чекбокс отмеченПроверить, что чекбокс не отмечен | cy.find('type="checkbox"').should('be.checked')cy.find('type="checkbox"').should('not.be.checked') |
Проверка наличия (видимости) элемента | Проверить, что видно поле вводаПроверить, что не виден чекбокс | cy.get(PageObject.TodoInput).should('be.visible')cy.find('type="checkbox"').should('not.be.visible') |
3. Остальные действия над элементом
Действие | Пример входного описания | Пример выходного кода |
---|---|---|
Прокрутка элемента (наверх, вниз, влево, вправо, в центр) | Пролистать поле ввода в центр | cy.get(PageObject.TodoInput).scrollTo('center') |
Прокрутка страницы к элементу | Пролистать страницу к полю ввода | cy.get(PageObject.TodoInput).scrollIntoView() |
Двойной клик по элементу | Дважды кликнуть по чекбоксу | cy.find('type="checkbox"').dblclick() |
Клик по элементу правой кнопкой мыши | Кликнуть правой кнопкой мыши по чекбоксу | cy.find('type="checkbox"').rightclick() |
Клик по элементу | Кликнуть элемент с текстом "Click me!" | cy.contains(Text.ClickMe).click() |
Отметить элемент (например, чекбокс) | Отметить чекбокс | cy.find('type="checkbox"').check() |
Снять отметку с элемента (например, чекбокса) | Снять отметку с чекбокса | cy.find('type="checkbox"').uncheck() |
Удалить введённый в элементе текст | Очистить текст в поле ввода | cy.get(PageObject.TodoInput).clear() |
Установить фокус (выделить) элемент | Установить фокус на поле ввода | cy.get(PageObject.TodoInput).focus() |
Снять фокус с элемента | Снять фокус с поля ввода | cy.get(PageObject.TodoInput).blur() |
Отправить элемент (создать событие submit, например, для формы) | Отправить форму регистрации | cy.get(PageObject.RegistrationForm).submit() |
Выбрать опцию в выпадающем списке (для элементов select) | Выбрать опцию "apples" в списке фруктов | cy.get(PageObject.FruitSelectList).select(Text.Apples) |
Ввести текст в элемент (кнопки клавиатуры указываются в фигурных скобках) | В поле ввода ввести "Feed the cat{enter}" | cy.get(PageObject.TodoInput).type(Text.FeedTheCatEnter) |