From 42cdf8c409161a6aad60a87f500529e92cc6dd77 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 4 Dec 2019 12:13:00 +0100 Subject: [PATCH] test(e2e): extract e2eUtils + test both api styles of todomvc --- packages/vue/examples/__tests__/e2eUtils.ts | 79 ++++++++ .../vue/examples/__tests__/todomvc.spec.ts | 177 +++++++----------- .../vue/examples/composition/todomvc.html | 6 +- 3 files changed, 149 insertions(+), 113 deletions(-) create mode 100644 packages/vue/examples/__tests__/e2eUtils.ts diff --git a/packages/vue/examples/__tests__/e2eUtils.ts b/packages/vue/examples/__tests__/e2eUtils.ts new file mode 100644 index 00000000..8fb8e73a --- /dev/null +++ b/packages/vue/examples/__tests__/e2eUtils.ts @@ -0,0 +1,79 @@ +import puppeteer from 'puppeteer' + +const puppeteerOptions = process.env.CI + ? { args: ['--no-sandbox', '--disable-setuid-sandbox'] } + : {} + +export function setupPuppeteer() { + let browser: puppeteer.Browser + let page: puppeteer.Page + + beforeEach(async () => { + browser = await puppeteer.launch(puppeteerOptions) + page = await browser.newPage() + }) + + afterEach(async () => { + await browser.close() + }) + + async function click(selector: string, options?: puppeteer.ClickOptions) { + await page.click(selector, options) + } + + async function count(selector: string) { + return (await page.$$(selector)).length + } + + async function text(selector: string) { + return await page.$eval(selector, node => node.textContent) + } + + async function value(selector: string) { + return await page.$eval(selector, (node: any) => node.value) + } + + async function isVisible(selector: string) { + const display = await page.$eval(selector, (node: HTMLElement) => { + return window.getComputedStyle(node).display + }) + return display !== 'none' + } + + async function isChecked(selector: string) { + return await page.$eval(selector, (node: any) => node.checked) + } + + async function classList(selector: string) { + return await page.$eval(selector, (node: any) => [...node.classList]) + } + + async function isFocused(selector: string) { + return await page.$eval(selector, node => node === document.activeElement) + } + + async function enterValue(selector: string, value: string) { + const el = (await page.$(selector))! + await el.evaluate((node: any) => (node.value = '')) + await el.type(value) + await el.press('Enter') + } + + async function clearValue(selector: string) { + return await page.$eval(selector, (node: any) => (node.value = '')) + } + + return { + page: () => page, + click, + count, + text, + value, + classList, + isVisible, + isChecked, + isFocused, + enterValue, + clearValue + } +} diff --git a/packages/vue/examples/__tests__/todomvc.spec.ts b/packages/vue/examples/__tests__/todomvc.spec.ts index a544b58d..a9df1dd5 100644 --- a/packages/vue/examples/__tests__/todomvc.spec.ts +++ b/packages/vue/examples/__tests__/todomvc.spec.ts @@ -1,34 +1,42 @@ import path from 'path' -import puppeteer from 'puppeteer' +import { setupPuppeteer } from './e2eUtils' -const puppeteerOptions = process.env.CI - ? { args: ['--no-sandbox', '--disable-setuid-sandbox'] } - : {} +describe('e2e: todomvc', () => { + const { + page, + click, + isVisible, + count, + text, + value, + isChecked, + isFocused, + classList, + enterValue, + clearValue + } = setupPuppeteer() -let browser: puppeteer.Browser -let page: puppeteer.Page + async function removeItemAt(n: number) { + const item = (await page().$('.todo:nth-child(' + n + ')'))! + const itemBBox = (await item.boundingBox())! + await page().mouse.move(itemBBox.x + 10, itemBBox.y + 10) + await click('.todo:nth-child(' + n + ') .destroy') + } -describe('e2e', () => { - beforeEach(async () => { - browser = await puppeteer.launch(puppeteerOptions) - page = await browser.newPage() - }) + async function testTodomvc(apiType: 'classic' | 'composition') { + const baseUrl = `file://${path.resolve( + __dirname, + `../${apiType}/todomvc.html` + )}` - afterEach(async () => { - await browser.close() - }) - - test('todomvc', async () => { - await page.goto( - `file://${path.resolve(__dirname, '../classic/todomvc.html')}` - ) + await page().goto(baseUrl) expect(await isVisible('.main')).toBe(false) expect(await isVisible('.footer')).toBe(false) expect(await count('.filters .selected')).toBe(1) expect(await text('.filters .selected')).toBe('All') expect(await count('.todo')).toBe(0) - await createNewItem('test') + await enterValue('.new-todo', 'test') expect(await count('.todo')).toBe(1) expect(await isVisible('.todo .edit')).toBe(false) expect(await text('.todo label')).toBe('test') @@ -39,31 +47,31 @@ describe('e2e', () => { expect(await isVisible('.clear-completed')).toBe(false) expect(await value('.new-todo')).toBe('') - await createNewItem('test2') + await enterValue('.new-todo', 'test2') expect(await count('.todo')).toBe(2) expect(await text('.todo:nth-child(2) label')).toBe('test2') expect(await text('.todo-count strong')).toBe('2') // toggle - await page.click('.todo .toggle') + await click('.todo .toggle') expect(await count('.todo.completed')).toBe(1) expect(await classList('.todo:nth-child(1)')).toContain('completed') expect(await text('.todo-count strong')).toBe('1') expect(await isVisible('.clear-completed')).toBe(true) - await createNewItem('test3') + await enterValue('.new-todo', 'test3') expect(await count('.todo')).toBe(3) expect(await text('.todo:nth-child(3) label')).toBe('test3') expect(await text('.todo-count strong')).toBe('2') - await createNewItem('test4') - await createNewItem('test5') + await enterValue('.new-todo', 'test4') + await enterValue('.new-todo', 'test5') expect(await count('.todo')).toBe(5) expect(await text('.todo-count strong')).toBe('4') // toggle more - await page.click('.todo:nth-child(4) .toggle') - await page.click('.todo:nth-child(5) .toggle') + await click('.todo:nth-child(4) .toggle') + await click('.todo:nth-child(5) .toggle') expect(await count('.todo.completed')).toBe(3) expect(await text('.todo-count strong')).toBe('2') @@ -78,7 +86,7 @@ describe('e2e', () => { expect(await text('.todo-count strong')).toBe('1') // remove all - await page.click('.clear-completed') + await click('.clear-completed') expect(await count('.todo')).toBe(1) expect(await text('.todo label')).toBe('test2') expect(await count('.todo.completed')).toBe(0) @@ -86,137 +94,86 @@ describe('e2e', () => { expect(await isVisible('.clear-completed')).toBe(false) // prepare to test filters - await createNewItem('test') - await createNewItem('test') - await page.click('.todo:nth-child(2) .toggle') - await page.click('.todo:nth-child(3) .toggle') + await enterValue('.new-todo', 'test') + await enterValue('.new-todo', 'test') + await click('.todo:nth-child(2) .toggle') + await click('.todo:nth-child(3) .toggle') // active filter - await page.click('.filters li:nth-child(2) a') + await click('.filters li:nth-child(2) a') expect(await count('.todo')).toBe(1) expect(await count('.todo.completed')).toBe(0) // add item with filter active - await createNewItem('test') + await enterValue('.new-todo', 'test') expect(await count('.todo')).toBe(2) // completed filter - await page.click('.filters li:nth-child(3) a') + await click('.filters li:nth-child(3) a') expect(await count('.todo')).toBe(2) expect(await count('.todo.completed')).toBe(2) // filter on page load - await page.goto( - `file://${path.resolve(__dirname, '../classic/todomvc.html#active')}` - ) + await page().goto(`${baseUrl}#active`) expect(await count('.todo')).toBe(2) expect(await count('.todo.completed')).toBe(0) expect(await text('.todo-count strong')).toBe('2') // completed on page load - await page.goto( - `file://${path.resolve(__dirname, '../classic/todomvc.html#completed')}` - ) + await page().goto(`${baseUrl}#completed`) expect(await count('.todo')).toBe(2) expect(await count('.todo.completed')).toBe(2) expect(await text('.todo-count strong')).toBe('2') // toggling with filter active - await page.click('.todo .toggle') + await click('.todo .toggle') expect(await count('.todo')).toBe(1) - await page.click('.filters li:nth-child(2) a') + await click('.filters li:nth-child(2) a') expect(await count('.todo')).toBe(3) - await page.click('.todo .toggle') + await click('.todo .toggle') expect(await count('.todo')).toBe(2) // editing triggered by blur - await page.click('.filters li:nth-child(1) a') - await page.click('.todo:nth-child(1) label', { clickCount: 2 }) + await click('.filters li:nth-child(1) a') + await click('.todo:nth-child(1) label', { clickCount: 2 }) expect(await count('.todo.editing')).toBe(1) expect(await isFocused('.todo:nth-child(1) .edit')).toBe(true) await clearValue('.todo:nth-child(1) .edit') - await page.type('.todo:nth-child(1) .edit', 'edited!') - await page.click('.new-todo') // blur + await page().type('.todo:nth-child(1) .edit', 'edited!') + await click('.new-todo') // blur expect(await count('.todo.editing')).toBe(0) expect(await text('.todo:nth-child(1) label')).toBe('edited!') // editing triggered by enter - await page.click('.todo label', { clickCount: 2 }) + await click('.todo label', { clickCount: 2 }) await enterValue('.todo:nth-child(1) .edit', 'edited again!') expect(await count('.todo.editing')).toBe(0) expect(await text('.todo:nth-child(1) label')).toBe('edited again!') // cancel - await page.click('.todo label', { clickCount: 2 }) + await click('.todo label', { clickCount: 2 }) await clearValue('.todo:nth-child(1) .edit') - await page.type('.todo:nth-child(1) .edit', 'edited!') - await page.keyboard.press('Escape') + await page().type('.todo:nth-child(1) .edit', 'edited!') + await page().keyboard.press('Escape') expect(await count('.todo.editing')).toBe(0) expect(await text('.todo:nth-child(1) label')).toBe('edited again!') // empty value should remove - await page.click('.todo label', { clickCount: 2 }) + await click('.todo label', { clickCount: 2 }) await enterValue('.todo:nth-child(1) .edit', ' ') expect(await count('.todo')).toBe(3) // toggle all - await page.click('.toggle-all+label') + await click('.toggle-all+label') expect(await count('.todo.completed')).toBe(3) - await page.click('.toggle-all+label') + await click('.toggle-all+label') expect(await count('.todo:not(.completed)')).toBe(3) + } + + test('classic', async () => { + await testTodomvc('classic') + }) + + test('composition', async () => { + await testTodomvc('composition') }) }) - -async function isVisible(selector: string) { - const display = await page.$eval(selector, (node: HTMLElement) => { - return window.getComputedStyle(node).display - }) - return display !== 'none' -} - -async function isChecked(selector: string) { - return await page.$eval(selector, (node: any) => node.checked) -} - -async function count(selector: string) { - return (await page.$$(selector)).length -} - -async function text(selector: string) { - return await page.$eval(selector, node => node.textContent) -} - -async function value(selector: string) { - return await page.$eval(selector, (node: any) => node.value) -} - -async function classList(selector: string) { - return await page.$eval(selector, (node: any) => [...node.classList]) -} - -async function isFocused(selector: string) { - return await page.$eval(selector, node => node === document.activeElement) -} - -async function clearValue(selector: string) { - return await page.$eval(selector, (node: any) => (node.value = '')) -} - -async function enterValue(selector: string, value: string) { - const el = (await page.$(selector))! - await el.evaluate((node: any) => (node.value = '')) - await el.type(value) - await el.press('Enter') -} - -async function createNewItem(text: string) { - const el = (await page.$('.new-todo'))! - await el.type(text) - await el.press('Enter') -} - -async function removeItemAt(n: number) { - const item = (await page.$('.todo:nth-child(' + n + ')'))! - const itemBBox = (await item.boundingBox())! - await page.mouse.move(itemBBox.x + 10, itemBBox.y + 10) - await page.click('.todo:nth-child(' + n + ') .destroy') -} diff --git a/packages/vue/examples/composition/todomvc.html b/packages/vue/examples/composition/todomvc.html index 0fba33f0..7a9de281 100644 --- a/packages/vue/examples/composition/todomvc.html +++ b/packages/vue/examples/composition/todomvc.html @@ -11,7 +11,7 @@ v-model="state.newTodo" @keyup.enter="addTodo"> -
+
    @@ -34,7 +34,7 @@
-