Введение
Созданный в 2014 году, Vue.js, несомненно, является одним из ведущих фронтенд-фреймворков на данный момент, и с растущим сообществом и расширяющейся экосистемой кажется, что его позиция будет прочной еще долгое время. Я работал с Vue 2 несколько лет назад в нескольких проектах и нашел это восхитительным опытом.
Я подумал, что сейчас самое время обновить свой набор инструментов до последней версии, а также до более новых инструментов, таких как Vite и Pinia.
В этом руководстве подробно описаны шаги по созданию функционального примера одностраничного приложения книжного магазина с использованием Vue 3 и его запуск с помощью Vite. Оно также содержит подробную информацию о том, как добавить управление состояниями с помощью Pinia (преемника Vuex) и маршрутизацию с помощью Vue Router.
Будут рассмотрены следующие основные концепции:
- создание одностраничного приложения Vue 3 с помощью Vite
- управление маршрутами с помощью Vue Router
- управление состоянием приложения с помощью Pinia
- запуск, создание и развертывание приложения с помощью Vite
- написание и выполнение тестов компонентов Vue
- написание и выполнение автоматизированных сквозных тестов с помощью Nightwatch.js.
Этого может показаться много, но я думаю, что вполне возможно пройти все это менее чем за 20 минут. Некоторые из перечисленных тем можно было бы развить в целые учебные пособия, но сейчас я рассказываю только о том, что необходимо для того, чтобы все было готово к работе.
И последнее, что необходимо упомянуть, это то, что бэкэнд в этом руководстве не рассматривается. Как такового компонента на стороне сервера нет, хотя данные загружаются с помощью Fetch API браузера (преемника XHR), поэтому компонент бэкенда можно легко добавить.
Для всех счетов и целей приложение, которое мы создадим здесь, может быть развернуто как статический веб-сайт. Если вам не терпится приступить к кодированию и вы хотите сразу же начать работу, вы можете просто запустить проект:
git clone https://github.com/beatfactor/middlemarch
npm install
npm run dev
Или форкнуть проект на Github по адресу: https://github.com/beatfactor/middlemarch.
Шаг 1 — Настройка приложения с помощью инструмента create-vite
Scaffolding Tool
Для настройки структуры проекта мы будем использовать официальный инструмент create-vite scaffolding tool, поэтому убедитесь, что у вас установлен Node 12+ с NPM 6+. Они также поддерживают Yarn и PNPM в качестве менеджеров пакетов, но мы рассмотрим только NPM.
Инструмент create-vite также создаст для вас папку проекта, поэтому сначала убедитесь, что вы вошли в родительскую папку: cd ~/workspace
.
Установите Vite
и инициализируйте проект:
npm init vite@latest
Затем вам будет предложено ввести имя проекта и выбрать библиотеку, которую вы хотите использовать. Из списка выберите vue
:
~/workspace % npm init vite@latest
npx: installed 6 in 1.051s
✔ Project name: … vue-bookstore
? Select a framework: › - Use arrow-keys. Return to submit.
vanilla
❯ vue
react
preact
lit
svelte
Затем выберите vue
в качестве варианта, поскольку мы не будем использовать TypeScript:
? Select a variant: › - Use arrow-keys. Return to submit.
❯ vue
vue-ts
Вы должны увидеть следующий результат:
npx: installed 6 in 1.051s
✔ Project name: … vue-bookstore
✔ Select a framework: › vue
✔ Select a variant: › vue
Scaffolding project in /Users/andrei/workspace/vue-bookstore...
Done. Now run:
cd vue-bookstore
npm install
npm run dev
После выполнения вышеуказанных инструкций мы получим следующий результат от Vite, сообщающий нам, что приложение запущено:
vite v2.7.7 dev server running at:
> Local: http://localhost:3000/
> Network: use `--host` to expose
ready in 611ms.
Давайте зайдем по адресу localhost:3000. Приветственная страница выглядит следующим образом:
Шаг 2 — Добавление маршрутизации с помощью Vue Router и управление состояниями с помощью Pinia
Рассмотрим структуру каталогов проекта, созданную инструментом create-vite
:
vue-bookstore/
├── public/
| ├── favicon.ico
├── src/
| ├── assets/
| | └── logo.png
| ├── components/
| | └── HelloWorld.vue
| ├── App.vue
| └── main.js
├─── package.json
├─── README.md
└─── vite.config.js
В этом разделе нашего руководства мы добавим две новые зависимости в наш проект: vue-router и pinia. Давайте продолжим и установим их из NPM.
Vue Router
Vue Router — это официальный маршрутизатор для Vue.js. Нам потребуется установить версию 4, которая совместима с Vue 3:
npm install vue-router@4 --save
Pinia
Pinia — один из самых новых проектов, появившихся в экосистеме Vue, и это новый официальный инструмент управления состоянием для приложений Vue.js. Его api очень похож на Vuex (его предшественника), и он разработан, чтобы быть более быстрым и легким.
Вы можете установить pinia из NPM с помощью:
npm install pinia --save
Настройка маршрутизации
Если вы не знакомы с маршрутизацией в одностраничном приложении или управлением состояниями, не волнуйтесь: обе эти концепции очень просты для понимания, и они сами собой объяснятся, как только вы увидите, как это работает.
Кроме того, помните, что мы создаем учебник, и наша цель — запустить все за 20 минут, а для этого не нужно изучать все, что можно знать о Vue.js. Это даже не требует понимания всего того, что мы будем делать.
Что такое одностраничное приложение?
Поскольку мы создаем одностраничное приложение, будет полезно (хотя и не обязательно) рассмотреть, что это значит и почему оно одностраничное.
Одностраничное приложение — это просто веб-приложение, которое не перезагружает страницу при переходе на другую ее подстраницу. Однако url браузера изменяется, как если бы страница была перезагружена, и это делается с помощью HTML5 History API.
Работа с компонентами Vue в Vite
Леса, созданные с помощью инструмента create-vite
, добавляют очень базовый компонент Vue, расположенный в src/components/HelloWorld.vue
. Затем он используется в основном компоненте приложения, расположенном в src/App.vue
.
Есть еще два важных файла:
- index.html
- src/main.js
Файл index.html — это то, что видит браузер при переходе на страницу нашего приложения, а main.js — это точка входа в приложение Vue.js.
Вот как выглядят эти файлы:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
src/main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Добавление маршрутов
Теперь пришло время создать основные маршруты нашего приложения. В Vue каждый маршрут должен соответствовать компоненту. Для этого приложения мы будем рассматривать компонент для каждой подстраницы, как показано ниже:
- Homepage — главная страница нашего книжного магазина
- Корзина — корзина и страница оформления заказа
- Sign-In — страница регистрации пользователя
Поскольку это только пример, другие страницы, такие как регистрация пользователя или страница подробного описания товара, были опущены. Кроме того, страница регистрации содержит только имитацию регистрации.
Для базового HTML и CSS я также использовал Bootstrap 5 для таких вещей, как выпадающие элементы пользовательского интерфейса и формы, но, конечно, вы можете использовать любую библиотеку пользовательского интерфейса, какую захотите.
Мы создадим компоненты страницы пустыми, чтобы мы могли настроить маршрутизацию. Новая структура каталога src будет выглядеть следующим образом (после удаления шаблонного кода):
src/
├── components/
| └── TopNavbar.js
├── lib/
| ├── router.js
| └── store.js
├── pages/
| ├── cart/
| | ├── cart.css
| | ├── cart.html
| | └── Cart.vue
| ├── home/
| | ├── home.css
| | ├── home.html
| | └── Home.vue
| ├── sign-in/
| | ├── sign-in.css
| | ├── sign-in.html
| | └── SignIn.vue
| └── routes.js
├── App.vue
└── main.js
Мы добавили три страницы, каждую из которых мы оставим очень простой. Мы просто добавим компонент TobNavbar
, чтобы навигация работала без перезагрузки страницы.
Добавьте следующее для src/pages/cart/Cart.vue
, src/pages/home/Home.vue
и src/pages/sign-in/SignIn.vue
:
<script setup>
import TopNavbar from '../../components/TopNavbar.vue';
</script>
<template>
<TopNavbar />
</template>
<style></style>
<script>
export default {
components: {
TopNavbar
},
computed: {},
mounted() {
},
data() {
return {
};
},
};
</script>
Компонент TopNavbar
, расположенный в src/components
, будет содержать только навигационные ссылки. Обратите внимание на компонент router-link, который является частью vue-router
:
<template>
<router-link to="/">Home</router-link>
<router-link to="/cart/">Cart</router-link>
<router-link to="/sign-in/">Sign In</router-link>
</template>
Файл pages/routes.js
содержит все объявления маршрутов для приложения. Вот как это выглядит:
import {createRouter} from 'vue-router'
import Homepage from './home/Home.vue';
import SignIn from './sign-in/SignIn.vue';
import Cart from './cart/Cart.vue';
const routes = [
{
path: '/',
component: Homepage
},
{
path: '/sign-in/',
component: SignIn
},
{
path: '/cart/',
component: Cart
},
]
export default function (history) {
return createRouter({
history,
routes
})
}
Прежде чем мы будем готовы увидеть vue-router
в действии, нам нужно сделать еще 2 вещи:
1) Создать маршрутизатор и добавить его в основной экземпляр приложения Vue в src/main.js
:
import { createApp } from 'vue'
import { createWebHistory } from 'vue-router'
import createRouter from './pages/routes.js'
import App from './App.vue'
const router = createRouter(createWebHistory())
const app = createApp(App)
app.use(router).mount('#app')
2)Добавьте компонент <router-view>
в src/App.vue
:
<template>
<router-view></router-view>
</template>
Теперь повторно запустите npm run dev
, если это необходимо, а затем перейдите по адресу http://localhost:3000
, и у вас будет приложение Vue 3 с поддержкой маршрутизации.
Настройка управления состояниями с помощью Pinia
Двигаемся дальше, теперь нам нужно настроить магазин Pinia для нашего приложения. Магазин — это место, где хранится состояние приложения.
Pinia — это новый проект основной команды Vue.js, и сейчас это рекомендуемый подход для работы с состоянием приложения. Если вы уже знакомы с Vuex, освоение Pinia будет простым. На самом деле, Pinia api немного проще и менее многословен, чем Vuex.
С Pinia в приложении Vue 3 есть один корневой магазин, а затем любое количество отдельных магазинов. Для нашего приложения книжного магазина мы будем использовать только два магазина:
- магазин каталога: список доступных книг
- магазин корзины: книги, которые пользователь хочет заказать.
Создание пинии
Пиния» — это корневое хранилище, которое мы должны сначала создать и передать его экземпляру Vue.
Мы сделаем это в src/main.js
и обновим его до вида:
import { createApp } from 'vue'
import { createWebHistory } from 'vue-router'
import { createPinia } from 'pinia'
import createRouter from './pages/routes.js'
import App from './App.vue'
const store = createPinia()
const router = createRouter(createWebHistory())
const app = createApp(App)
app.use(router).use(store).mount('#app')
Следующим шагом будет создание отдельных магазинов каталога и корзины и использование их в компонентах.
Добавление магазина каталога
Создание магазина Pinia означает в основном две вещи:
- определение магазина
- использование магазина в одном или нескольких компонентах
Определение магазина
Как и в Vuex, магазин Pinia содержит состояние и два типа методов: getters и actions.
Некоторые вещи, которые следует учитывать при работе с магазином:
state
определяется как функция, возвращающая начальное состояние.
Теперь пришло время создать магазин каталога внутри src/stores/catalog.js
:
import { defineStore } from 'pinia'
export const useCatalog = defineStore('catalog-store', {
state: () => {
return {
newArrivals: [],
fetching: false
}
},
getters: {
results(state) {
return state.newArrivals;
},
isFetching(state) {
return state.fetching;
}
},
actions: {
async fetchNewArrivals() {
this.fetching = true;
const response = await fetch('/data/new-arrivals.json');
try {
const result = await response.json();
this.newArrivals = result.books;
} catch (err) {
this.newArrivals = [];
console.error('Error loading new arrivals:', err);
return err;
}
this.fetching = false;
}
}
})
Взглянув на приведенный выше исходный код, вы заметите, что у нас есть два геттера (results
и isFetching
) и одно действие (fetchNewArrivals
). Вместо реального бэкенда у нас просто есть json-файл, расположенный в /data/new-arrivals.json
, который содержит несколько книг, которые мы будем использовать в качестве нашего каталога.
Вы также заметите, что наши геттеры не делают ничего особенного с данными, поэтому они немного излишни, но я подумал, что все равно будет полезно показать, как их можно определить.
Использование хранилища в шаблоне
Связать приведенное выше определение с шаблоном также довольно просто.
Давайте создадим новый компонент NewArrivals
внутри src/components/NewArrivals.vue
, который мы будем использовать в компоненте страницы Home.vue
.
<script setup>
import {useCatalog} from '../../store/catalog.js'
</script>
<template>
</template>
<style scoped></style>
<script>
import { mapState, mapActions } from 'pinia'
export default {
computed: {
...mapState(useCatalog, {newArrivals: 'results'})
},
methods: {
...mapActions(useCatalog, ['fetchNewArrivals']),
addToCart() {
// we'll populate this later
}
},
created() {
// when the template is created, we call this action
this.fetchNewArrivals();
}
};
</script>
И компонент Home.vue
становится:
<script setup>
import TopNavbar from '../../components/TopNavbar.vue';
import NewArrivals from '../../components/NewArrivals.vue';
</script>
<template>
<TopNavbar />
<NewArrivals />
</template>
<style></style>
<script>
export default {
components: {
TopNavbar,
NewArrivals
},
computed: {},
mounted() {},
data() {
return {};
},
};
</script>
Вот диаграмма того, как магазин и компонент работают вместе в приложении:
Я также написал магазин и компонент для корзины, но я не буду включать его в учебник, потому что механизм похож, и вы можете просмотреть исходный код в репозитории, в котором все добавлено вместе, даже некоторые стили.
Шаг 3 — Тестирование компонентов Vue.js
Тестирование компонентов — это тип тестирования пользовательского интерфейса, при котором компонент отображается изолированно, без остальных компонентов приложения, с целью проверки его функциональности. Обычно это стратегия тестирования, которая проводится до этапа сквозного тестирования, о котором мы расскажем в следующем разделе.
Нам нужно установить проект Vue TestUtils, который является официальной библиотекой модульного тестирования для Vue.js, и нам нужна та, которая предназначена для Vue 3. Вы можете установить его из NPM с помощью:
npm install @vue/test-utils@next --save-dev
Установка Nightwatch.js и ChromeDriver
Мы будем использовать Nightwatch.js как для тестирования компонентов, так и для сквозного тестирования. Nightwatch уже является одним из рекомендуемых командой Vue.js фреймворков для тестирования и был опубликован примерно в то же время, что и Vue.
Недавно он получил поддержку (пока еще бета-версию) для тестирования компонентов Vue через vite-plugin-nightwatch. Мы установим Nightwatch v2, используя:
npm install nightwatch--save-dev
Также нам понадобится vite-plugin-nightwatch
, упомянутый ранее:
npm install vite-plugin-nightwatch --save-dev
Nightwatch использует W3C WebDriver API для задач автоматизации браузера, и нам понадобится установить пакет NPM chromedriver
, поскольку мы собираемся использовать Chrome для запуска наших тестов.
npm install chromedriver --save-dev
Тестирование компонента <NewArrivals>.
И вот мы подошли к тому моменту, когда можно наконец-то начать писать реальный тест для нашего компонента NewArrivals.
Упомянутый ранее vite-plugin-nightwatch
включает в себя страницу тестового рендеринга, а Nightwatch уже содержит все необходимое для проведения начального теста нашего компонента.
Создайте папку test
и внутри нее две подпапки:
Нам также понадобится конфигурационный файл nightwatch.conf.js
, но мы можем запустить Nightwatch напрямую, и конфигурационный файл будет создан для нас автоматически. Просто убедитесь, что chromedriver
также установлен (и браузер Chrome, конечно).
Убедитесь, что текущий рабочий каталог является корнем проекта, а затем просто запустите пример теста, который поставляется в комплекте с Nightwatch. Мы выберем тест duckDuckGo
, потому что он самый быстрый:
$ npx nightwatch examples/tests/duckDuckGo.js
Теперь структура проекта должна выглядеть следующим образом:
vue-bookstore/
├── public/
| ├── data/
| └── favicon.ico
├── src/
├── ...
| └── main.js
├── test/
| ├── component/
| └── e2e/
├─── nightwatch.conf.js
├─── package.json
├─── README.md
└─── vite.config.js
Создадим новый файл newArrivalsTest.js
внутри test/component
. В нем мы просто добавим базовый тест, который монтирует компонент и проверяет, можно ли найти возвращаемый элемент на странице (т.е. компонент был смонтирован).
describe('New Arrivals Component Test', function() {
it('checks if the component has been mounted', async (browser) => {
const component = await browser.mountVueComponent('/src/components/new-arrivals/NewArrivals.vue', {
plugins: {
router: '/src/lib/router.js'
}
})
expect(component).to.be.present;
});
});
Nightwatch использует тот же синтаксис describe()
, что и Mocha. Вы даже можете использовать Mocha в качестве прогона тестов, если вы уже знакомы с ним, но мы пока не будем этого делать. В случае если вы хотите использовать Mocha, вам нужно всего лишь вставить несколько переключателей в конфигурационный файл nightwatch, и на сайте Nightwatch есть документация о том, как это сделать.
Теперь пришло время выполнить вышеупомянутый тест, и для этого мы запустим Nightwatch с помощью Chrome, как показано ниже:
npx nightwatch test/component/newArrivalsTest.js --env chrome
Это откроет браузер Chrome и отобразит компонент, а затем выполнит тест. Если вам не нравится видеть всплывающее окно браузера во время теста, вы можете передать аргумент --headless
, как показано ниже:
npx nightwatch test/component/newArrivalsTest.js --env chrome --headless
Вывод теста должен выглядеть следующим образом:
[New Arrivals Component Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (652ms).
Using: chrome (97.0.4692.99) on MAC OS X.
Running tests the component:
──────────────────────────────────────────────────────────────
✔ Expected element <web element{e53f9b1e-11d3-4dc4-8728-4d3cd077343e}> to be present (1ms)
OK. 1 assertions passed. (781ms)
Конечно, вы можете ознакомиться со всеми опциями CLI, которые предоставляет программа Nightwatch runner, перейдя на страницы документации или выполнив команду:
npx nightwatch --help
Расширение <NewArrivals> теста
Вы, наверное, заметили, что наш компонентный тест тестирует не так много, что означает, что тест не так полезен, как мог бы быть. Поэтому мы немного расширим его.
Мы просто проверим компонент NewArrivals
и проверим, есть ли в нем свойство newArrivals
, которое используется в html для вывода результатов.
Теперь тест выглядит следующим образом. Мы рефакторизовали установку компонента в хук before
, чтобы мы могли выполнять проверки только внутри теста, который является блоком it
. Библиотека expect
предоставляется Nightwatch из коробки и основана на популярной и универсальной библиотеке утверждений Chai.js. Подробнее о том, как использовать expect
на сайте документации Nightwatch.
describe('New Arrivals Component Test', function() {
let component;
before(async () => {
component = await browser.mountVueComponent('/src/components/new-arrivals/NewArrivals.vue', {
plugins: {
router: '/src/lib/router.js'
}
})
});
it('checks if the component has been mounted', function(browser) {
expect(component).to.be.present;
expect(component).to.have.property('newArrivals');
expect(component).text.toContain('The Memory Police')
expect.elements('div.col-md-6').count.toEqual(4); expect(component.property('newArrivals')).to.be.an('array').with.length(1);
});
});
Шаг 4 — Конечное тестирование приложения Vue.js
Мы подходим к концу этого руководства, и прежде чем мы сможем считать, что у нас есть работающее приложение Vue.js, нам нужно добавить поддержку сквозного тестирования и настроить CI-конвейер на Github Actions.
К счастью, нам не нужно ни устанавливать, ни настраивать какие-либо другие инструменты, за исключением, возможно, некоторых причудливых репортеров, но пока мы можем получить все необходимое для сквозного автоматизированного тестирования из Nightwatch. Помимо Chrome, Nightwatch имеет встроенную поддержку всех основных браузеров, включая Firefox, Edge и Safari, благодаря интеграции с W3C Webdriver API и Selenium. Он также позволяет использовать распределенные облачные платформы тестирования, такие как BrowserStack, SauceLabs, CrossBrowserTesting или LambdaTest.
На данный момент мы не будем усложнять ситуацию и сосредоточимся только на написании нескольких базовых автоматизированных тестов и их запуске в Chrome, Firefox и Safari.
Написание сквозного теста домашней страницы
Давайте начнем со сквозного теста домашней страницы и создадим новый файл test/e2e/homePageTest.js
. Синтаксис такой же, как и для компонентного теста, но для запуска сквозных тестов мы будем использовать скомпилированную сборку нашего приложения.
Конечно, мы можем запустить их на dev-сборке, но общепринятая практика в разработке программного обеспечения, насколько я могу судить, заключается в том, чтобы запускать сквозные тесты в среде, максимально приближенной к производственной. Именно поэтому они называются сквозными тестами, я полагаю, чтобы проводить их на конечном продукте.
Запуск производственной сборки
Для запуска производственной сборки у нас есть несколько вариантов, и каждый из них предполагает выполнение команды Vite
, которая обернута в задачу NPM.
Второй вариант явно более простой, поэтому давайте просто выполним команду preview
и посмотрим, что произойдет:
$ npm run preview
> vue-bookstore@0.0.0 preview /Users/andrei/workspace/vue-bookstore
> vite preview
> Local: http://localhost:5000/
> Network: use `--host` to expose
Написание сценария теста
Теперь, когда у нас есть готовая к производству сборка, мы можем начать писать настоящий тест в test/e2e/homePageTest.js
. Мы начнем с малого, с нижеприведенного:
describe('Homepage End-to-end Test', () => {
it('tests if homepage is loaded', browser => {
browser
.navigateTo('http://localhost:3000')
.assert.visible('#app .new-arrivals-panel')
.expect.elements('#app .new-arrivals-panel .col-md-6').count.toEqual(4)
});
it('adds 2 volumes of "Rhinoceros and Other Plays" to cart', browser => {
browser
.click('.new-arrivals-panel .col-md-6:nth-child(2) button.add-to-cart')
.click('.new-arrivals-panel .col-md-6:nth-child(2) button.add-to-cart')
.assert.textEquals('.shopping-cart .badge', '2');
});
after(browser => browser.end());
});
Тест проверяет, отображается ли панель «Новые поступления» на странице и содержит ли она все 4 записи, которые мы уже видели.
Запуск тестового сценария в Chrome
Чтобы запустить тест в Chrome, команда очень похожа на команду для теста компонента:
npx nightwatch test/e2e/homePageTest.js --env chrome
Вывод будет следующим:
[Homepage End-to-end Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (2454ms).
Using: chrome (97.0.4692.99) on MAC OS X.
Running tests the homepage:
──────────────────────────────────────────────────────────────
✔ Testing if element <#app .new-arrivals-panel> is visible (157ms)
✔ Expected elements <#app .new-arrivals-panel .col-md-6> count to equal: "4" (18ms)
OK. 2 assertions passed. (765ms)
Запуск сценария тестирования в Firefox
Если мы хотим также запускать наши сквозные тесты в браузере Firefox, нам нужно только установить GeckoDriver (специфическая для Firefox реализация W3C WebDriver API). Никаких других настроек для работы не требуется, если только вы не хотите настроить его дополнительно.
Итак, давайте продолжим и установим его из NPM:
npm i geckodriver --save-dev
Затем запустите Nightwatch с помощью следующей команды:
npx nightwatch test/e2e/homePageTest.js --env firefox
И вывод:
[Homepage End-to-end Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to GeckoDriver on port 4444 (1737ms).
Using: firefox (96.0.2) on MAC (20.6.0).
Running tests the homepage:
──────────────────────────────────────────────────────────────
✔ Testing if element <#app .new-arrivals-panel> is visible (54ms)
✔ Expected elements <#app .new-arrivals-panel .col-md-6> count to equal: "4" (6ms)
OK. 2 assertions passed. (612ms)
Запуск тестового сценария в Safari
Если вы используете Mac, то safaridriver
, вероятно, уже установлен, в зависимости от версии Safari.
Вы можете проверить это с помощью:
safaridriver --help
Результат должен выглядеть следующим образом:
Usage: safaridriver [options]
-h, --help Prints out this usage information.
--version Prints out version information and exits.
-p, --port Port number the driver should use. If the server is already running, the port cannot be changed. If port 0 is specified, a default port will be used.
--enable Applies configuration changes so that subsequent WebDriver sessions will run without further authentication.
--diagnose Causes safaridriver to log diagnostic information for all sessions hosted by this instance. See the safaridriver(1) man page for more details about diagnostic logging.
Перед запуском первого теста в Safari необходимо включить автоматизацию с помощью следующей команды:
safaridriver --enable
А затем просто запустите тест «Ночной дозор» с помощью команды:
npx nightwatch test/e2e/homePageTest.js --env safari
Параллельный запуск в нескольких браузерах
Если вам нужно запустить тесты Nightwatch (компонентные или сквозные) в нескольких браузерах, вы можете сделать это параллельно в нескольких браузерах.
Просто передайте браузеры в виде списка, разделенного запятыми (без пробелов:
Запуск в Firefox+Chrome
npx nightwatch test/e2e/homePageTest.js --env firefox,chrome
Работает в Firefox+Chrome+Safari
npx nightwatch test/e2e/homePageTest.js --env firefox,chrome,safari
Nightwatch также поддерживает параллельный запуск тестов, разделяя общее количество файлов тестовых сценариев на настраиваемое количество рабочих. Но поскольку у нас пока только один файл, мы пропустим эту часть. Подробнее о параллелизме на сайте документации Nightwatch.
Шаг 5 — Включение непрерывной интеграции с помощью Github Actions
Похоже, пришло время подвести итоги и собрать все воедино. Прежде чем мы сможем включить непрерывное развертывание в Github Actions, нам нужно создать задачу NPM test
.
Создание задачи «npm test»
Теперь у нас есть и компонентное, и сквозное тестирование в нашем примере проекта. Конечно, это только минимальный уровень, поэтому он не охватывает всего, но это хорошее начало, я бы сказал.
Самый простой способ указать Nightwatch на запуск всех тестов внутри папки test — это передать папку в качестве второго аргумента CLI. Мы добавим это как новую задачу NPM под названием test
, поэтому давайте отредактируем package.json
и добавим следующее, внутри словаря «scripts»:
{
"test": "nightwatch ./test"
}
Мы можем запустить задачу NPM и передать CLI-аргументы, связанные с Nightwatch, следующим образом:
npm test -- --env chrome --headless
Мы будем использовать режим --headless
для запуска тестов в Github Actions.
Добавление рабочего процесса Github Action
Наконец, мы можем добавить рабочий процесс Github Actions, чтобы наши тесты запускались при каждом push и каждом pull request.
Сделать это довольно просто. Мы воспользуемся шаблоном Node.js и добавим несколько новых шагов в список, например:
- запуска dev-сервера в фоновом режиме
- сборка проекта и запуск dev-сервера в режиме предварительного просмотра, также в фоновом режиме
- запуска компонентных и сквозных тестов в Chrome в режиме headless.
Создание рабочего процесса Github Actions означает добавление нового файла node.js.yml в папку .github/workflows
, который должен выглядеть следующим образом. Большая часть этого файла создается автоматически, когда вы переходите в раздел Actions из вашего проекта Github и выбираете шаблон Node.js.
name: Node.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Start vite dev server
run: npm run dev &
- name: Build the app
run: npm run build
- name: Start vite dev server in preview
run: npm run preview &
- name: Run Nightwatch tests
run: npm test
Вот и все. Новая сборка будет запускаться при каждом новом git push или при отправке нового pull request. Сборка будет запускаться в двух отдельных окружениях, одно для Node 12, а другое для Node 14, как указано в определении рабочего процесса.
Куда двигаться дальше
Проект доступен на Github по адресу https://github.com/beatfactor/middlemarch и содержит весь код, описанный здесь, а также немного больше стилизации и изображений. Он также содержит код для корзины и макет страницы оформления заказа.
Вы можете запустить его на своей локальной машине, выполнив обычные действия:
git clone https://github.com/beatfactor/middlemarch
npm install
npm run dev
Не стесняйтесь отправлять запросы на исправление или сообщать о проблемах.
Получение поддержки
Vue3, Vite и Pinia**
Основная команда Vue.js предоставляет поддержку сообществу для Vue3, Vite и Pinia по следующим каналам:
- Чат-сервер VueLand на Discord
- Форум Vue
- Обсуждения Vite на Github
- Обсуждения Pinia на Github
Nightwatch.js
Для поддержки всего, что связано с тестированием Nightwatch, у нас есть следующие каналы:
- Обсуждения на Github
- Чат-сервер Nightwatch.js на Discord