npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

kipascriber

v1.4.0

Published

Tool for generating client side functional tests from a description in natural language.

Downloads

320

Readme

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) |