e3cf05f408
This PR replaces our webdriver end to end tests with playwright tests. It: - replaces our webdriver workflow with a new e2e workflow based on playwright - removes the webdriver project - adds e2e tests to our examples app - replaces all `data-wd` attributes with `data-testid` ### Coverage Most of the tests from our previous e2e tests are reproduced here, though there are some related to our gestures that will need to be done in a different way—or not at all. I've also added a handful of new tests, too. ### Where are they The tests are now part of our examples app rather than being in its own different app. This should help us test our different examples too. As far as I can tell there are no downsides here in terms of the regular developer experience, though they might complicate any CodeSandbox projects that are hooked into the examples app. ### Change Type - [x] `tests` — Changes to any testing-related code only (will not publish a new version)
323 lines
9.2 KiB
TypeScript
323 lines
9.2 KiB
TypeScript
import test, { Page, expect } from '@playwright/test'
|
|
import { setupPage, setupPageWithShapes } from '../shared-e2e'
|
|
|
|
declare const __tldraw_ui_event: { name: string }
|
|
|
|
// We're just testing the events, not the actual results.
|
|
|
|
let page: Page
|
|
|
|
test.describe('Keyboard Shortcuts', () => {
|
|
test.beforeAll(async ({ browser }) => {
|
|
page = await browser.newPage()
|
|
await setupPage(page)
|
|
})
|
|
|
|
test('tools', async () => {
|
|
const geoToolKds = [
|
|
['r', 'rectangle'],
|
|
['o', 'ellipse'],
|
|
]
|
|
|
|
for (const [key, geo] of geoToolKds) {
|
|
await page.keyboard.press('v') // set back to select
|
|
await page.keyboard.press(key)
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'select-tool',
|
|
data: { id: `geo-${geo}`, source: 'kbd' },
|
|
})
|
|
}
|
|
|
|
const simpleToolKbds = [
|
|
['v', 'select'],
|
|
['h', 'hand'],
|
|
]
|
|
|
|
for (const [key, tool] of simpleToolKbds) {
|
|
await page.keyboard.press('v') // set back to select
|
|
await page.keyboard.press(key)
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'select-tool',
|
|
data: { id: tool, source: 'kbd' },
|
|
})
|
|
}
|
|
|
|
const shapeToolKbds = [
|
|
['d', 'draw'],
|
|
['x', 'draw'],
|
|
['a', 'arrow'],
|
|
['l', 'line'],
|
|
['f', 'frame'],
|
|
['n', 'note'],
|
|
['f', 'frame'],
|
|
['e', 'eraser'],
|
|
['k', 'laser'],
|
|
['t', 'text'],
|
|
]
|
|
|
|
for (const [key, tool] of shapeToolKbds) {
|
|
await page.keyboard.press('v') // set back to select
|
|
await page.keyboard.press(key)
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'select-tool',
|
|
data: { id: tool, source: 'kbd' },
|
|
})
|
|
}
|
|
})
|
|
|
|
test.describe('actions', () => {
|
|
test('Zoom in', async () => {
|
|
await page.keyboard.press('Control+=')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'zoom-in',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Zoom out', async () => {
|
|
await page.keyboard.press('Control+-')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'zoom-out',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Zoom to fit', async () => {
|
|
await page.keyboard.press('Shift+1')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'zoom-to-fit',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Zoom to selection', async () => {
|
|
await page.keyboard.press('Shift+2')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'zoom-to-selection',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Zoom to 100', async () => {
|
|
await page.keyboard.press('Shift+0')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'reset-zoom',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
/* ---------------------- Files --------------------- */
|
|
|
|
// new-project — Cmd+N
|
|
// open — Cmd+O
|
|
// save — Cmd+S
|
|
// save-as — Cmd+Shift+S
|
|
// upload-media — Cmd+I
|
|
|
|
/* -------------------- Clipboard ------------------- */
|
|
|
|
// await page.keyboard.press('Control+c')
|
|
// expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
// name: 'copy',
|
|
// data: { source: 'kbd' },
|
|
// })
|
|
|
|
// await page.keyboard.press('Control+v')
|
|
// expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
// name: 'paste',
|
|
// data: { source: 'kbd' },
|
|
// })
|
|
|
|
// await page.keyboard.press('Control+x')
|
|
// expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
// name: 'cut',
|
|
// data: { source: 'kbd' },
|
|
// })
|
|
|
|
/* ------------------- Preferences ------------------ */
|
|
|
|
test('Toggle grid mode', async () => {
|
|
await page.keyboard.press("Control+'")
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'toggle-grid-mode',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Toggle dark mode', async () => {
|
|
await page.keyboard.press('Control+/')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'toggle-dark-mode',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
test('Toggle tool lock', async () => {
|
|
await page.keyboard.press('q')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'toggle-tool-lock',
|
|
data: { source: 'kbd' },
|
|
})
|
|
})
|
|
|
|
/* -------------- Operations on Shapes -------------- */
|
|
|
|
test('Operations on shapes', async () => {
|
|
await setupPageWithShapes(page)
|
|
|
|
// select-all — Cmd+A
|
|
await page.keyboard.press('Control+a')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'select-all-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// distribute horizontal
|
|
await page.keyboard.press('Control+a')
|
|
await page.mouse.click(200, 200, { button: 'right' })
|
|
await page.getByTestId('menu-item.arrange').click()
|
|
await page.getByTestId('menu-item.distribute-horizontal').click()
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'distribute-shapes',
|
|
data: { operation: 'horizontal', source: 'context-menu' },
|
|
})
|
|
|
|
// distribute vertical — Shift+Alt+V
|
|
await page.keyboard.press('Control+a')
|
|
await page.mouse.click(200, 200, { button: 'right' })
|
|
await page.getByTestId('menu-item.arrange').click()
|
|
await page.getByTestId('menu-item.distribute-vertical').click()
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'distribute-shapes',
|
|
data: { operation: 'vertical', source: 'context-menu' },
|
|
})
|
|
|
|
// flip-h — Shift+H
|
|
await page.keyboard.press('Shift+h')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'flip-shapes',
|
|
data: { operation: 'horizontal', source: 'kbd' },
|
|
})
|
|
|
|
// flip-v — Shift+V
|
|
await page.keyboard.press('Shift+v')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'flip-shapes',
|
|
data: { operation: 'vertical', source: 'kbd' },
|
|
})
|
|
|
|
// move-to-front — ]
|
|
await page.keyboard.press(']')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'reorder-shapes',
|
|
data: { operation: 'toFront', source: 'kbd' },
|
|
})
|
|
|
|
// move-forward — Alt+]
|
|
await page.keyboard.press('Alt+]')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'reorder-shapes',
|
|
data: { operation: 'forward', source: 'kbd' },
|
|
})
|
|
|
|
// move-to-back — [
|
|
await page.keyboard.press('[')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'reorder-shapes',
|
|
data: { operation: 'toBack', source: 'kbd' },
|
|
})
|
|
|
|
// move-backward — Alt+[
|
|
await page.keyboard.press('Alt+[')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'reorder-shapes',
|
|
data: { operation: 'backward', source: 'kbd' },
|
|
})
|
|
|
|
// group — Cmd+G
|
|
await page.keyboard.press('Control+g')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'group-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// ungroup — Cmd+Shift+G
|
|
await page.keyboard.press('Control+Shift+g')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'ungroup-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// duplicate — Cmd+D
|
|
await page.keyboard.press('Control+d')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'duplicate-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// delete — backspace
|
|
await page.keyboard.press('Backspace')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'delete-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// delete — ⌫
|
|
await page.keyboard.press('Delete')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'delete-shapes',
|
|
data: { source: 'kbd' },
|
|
})
|
|
|
|
// align left — Alt+A
|
|
await page.keyboard.press('Alt+a')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'align-shapes',
|
|
data: { operation: 'left', source: 'kbd' },
|
|
})
|
|
|
|
// align right — Alt+D
|
|
await page.keyboard.press('Alt+d')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'align-shapes',
|
|
data: { operation: 'right', source: 'kbd' },
|
|
})
|
|
|
|
// align top — Alt+W
|
|
await page.keyboard.press('Alt+w')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'align-shapes',
|
|
data: { operation: 'top', source: 'kbd' },
|
|
})
|
|
|
|
// align bottom — Alt+W'
|
|
await page.keyboard.press('Alt+s')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'align-shapes',
|
|
data: { operation: 'bottom', source: 'kbd' },
|
|
})
|
|
|
|
/* ---------------------- Misc ---------------------- */
|
|
|
|
// await page.keyboard.press('Control+i')
|
|
// expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
// name: 'open-menu',
|
|
// data: { source: 'dialog' },
|
|
// })
|
|
|
|
// await page.keyboard.press('Control+u')
|
|
// expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
// name: 'open-menu',
|
|
// data: { source: 'dialog' },
|
|
// })
|
|
|
|
/* --------------------- Export --------------------- */
|
|
|
|
await page.keyboard.press('Control+Shift+c')
|
|
expect(await page.evaluate(() => __tldraw_ui_event)).toMatchObject({
|
|
name: 'copy-as',
|
|
data: { format: 'svg', source: 'kbd' },
|
|
})
|
|
})
|
|
})
|
|
})
|