migration to vite/playwright
This commit is contained in:
45
tests/e2e/clipboard.spec.js
Normal file
45
tests/e2e/clipboard.spec.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { clickCanvas, setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
const SAMPLE_SVG = `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<circle cx="100" cy="100" r="50" fill="#FF0000" id="testCircle" stroke="#000000" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>`
|
||||
|
||||
test.describe('Clipboard', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
await setSvgSource(page, SAMPLE_SVG)
|
||||
await expect(page.locator('#testCircle')).toBeVisible()
|
||||
})
|
||||
|
||||
test('copy, paste, cut and delete shapes', async ({ page }) => {
|
||||
await page.locator('#testCircle').click({ button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#copy"]').click()
|
||||
|
||||
await clickCanvas(page, { x: 200, y: 200 })
|
||||
await page.locator('#svgroot').click({ position: { x: 200, y: 200 }, button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#paste"]').click()
|
||||
|
||||
await expect(page.locator('#svg_1')).toBeVisible()
|
||||
await expect(page.locator('#svg_2')).toHaveCount(0)
|
||||
|
||||
await page.locator('#testCircle').click({ button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#cut"]').click()
|
||||
await expect(page.locator('#testCircle')).toHaveCount(0)
|
||||
await expect(page.locator('#svg_1')).toBeVisible()
|
||||
|
||||
await page.locator('#svgroot').click({ position: { x: 240, y: 240 }, button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#paste"]').click()
|
||||
await expect(page.locator('#svg_2')).toBeVisible()
|
||||
|
||||
await page.locator('#svg_2').click({ button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#delete"]').click()
|
||||
await page.locator('#svg_1').click({ button: 'right' })
|
||||
await page.locator('#cmenu_canvas a[href="#delete"]').click()
|
||||
await expect(page.locator('#svg_1')).toHaveCount(0)
|
||||
await expect(page.locator('#svg_2')).toHaveCount(0)
|
||||
})
|
||||
})
|
||||
21
tests/e2e/control-points.spec.js
Normal file
21
tests/e2e/control-points.spec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Control points', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('dragging arc path control points keeps path valid', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path d="m187,194a114,62 0 1 0 219,2" id="svg_1" fill="#FF0000" stroke="#000000" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
|
||||
const d = await page.locator('#svg_1').getAttribute('d')
|
||||
expect(d).toBeTruthy()
|
||||
expect(d).not.toContain('NaN')
|
||||
})
|
||||
})
|
||||
19
tests/e2e/export.spec.js
Normal file
19
tests/e2e/export.spec.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { openMainMenu, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Export', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('export button visible in menu', async ({ page }) => {
|
||||
await openMainMenu(page)
|
||||
await expect(page.locator('#tool_export')).toBeVisible()
|
||||
})
|
||||
|
||||
test('export dialog opens', async ({ page }) => {
|
||||
await openMainMenu(page)
|
||||
await page.locator('#tool_export').click()
|
||||
await expect(page.locator('#dialog_content select')).toBeVisible()
|
||||
})
|
||||
})
|
||||
20
tests/e2e/fixtures.js
Normal file
20
tests/e2e/fixtures.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { test as base, expect } from '@playwright/test'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
// Playwright fixture that captures Istanbul coverage from instrumented builds.
|
||||
export const test = base.extend({
|
||||
page: async ({ page }, use, testInfo) => {
|
||||
await use(page)
|
||||
const coverage = await page.evaluate(() => globalThis.__coverage__ || null)
|
||||
if (!coverage) return
|
||||
|
||||
const nycDir = path.join(process.cwd(), '.nyc_output')
|
||||
fs.mkdirSync(nycDir, { recursive: true })
|
||||
const slug = testInfo.title.replace(/[^\w-]+/g, '_')
|
||||
const file = path.join(nycDir, `playwright-${slug}.json`)
|
||||
fs.writeFileSync(file, JSON.stringify(coverage))
|
||||
}
|
||||
})
|
||||
|
||||
export { expect }
|
||||
67
tests/e2e/helpers.js
Normal file
67
tests/e2e/helpers.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
export async function visitAndApproveStorage (page) {
|
||||
await page.goto('about:blank')
|
||||
await page.context().clearCookies()
|
||||
await page.goto('/index.html')
|
||||
await page.evaluate(() => {
|
||||
localStorage.clear()
|
||||
sessionStorage.clear()
|
||||
})
|
||||
await page.reload()
|
||||
const storageOk = page.locator('#storage_ok')
|
||||
if (await storageOk.count()) {
|
||||
await storageOk.click()
|
||||
} else {
|
||||
await page.waitForSelector('#svgroot', { timeout: 20000 })
|
||||
}
|
||||
await selectEnglishAndSnap(page)
|
||||
}
|
||||
|
||||
export async function selectEnglishAndSnap (page) {
|
||||
await page.waitForFunction(() => window.svgEditor && window.svgEditor.setConfig, null, { timeout: 20000 })
|
||||
await page.evaluate(() => {
|
||||
window.svgEditor.setConfig({
|
||||
lang: 'en',
|
||||
gridSnapping: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function openMainMenu (page) {
|
||||
await page.locator('#main_button').click()
|
||||
}
|
||||
|
||||
export async function setSvgSource (page, svgMarkup) {
|
||||
await page.locator('#tool_source').click()
|
||||
const textarea = page.locator('#svg_source_textarea')
|
||||
await expect(textarea).toBeVisible()
|
||||
await textarea.fill(svgMarkup)
|
||||
await page.locator('#tool_source_save').click()
|
||||
}
|
||||
|
||||
export async function clickCanvas (page, point) {
|
||||
const canvas = page.locator('#svgroot')
|
||||
const box = await canvas.boundingBox()
|
||||
if (!box) {
|
||||
throw new Error('Could not determine canvas bounds')
|
||||
}
|
||||
await page.mouse.click(box.x + point.x, box.y + point.y)
|
||||
}
|
||||
|
||||
export async function dragOnCanvas (page, start, end) {
|
||||
const canvas = page.locator('#svgroot')
|
||||
const box = await canvas.boundingBox()
|
||||
if (!box) {
|
||||
throw new Error('Could not determine canvas bounds')
|
||||
}
|
||||
const startX = box.x + start.x
|
||||
const startY = box.y + start.y
|
||||
const endX = box.x + end.x
|
||||
const endY = box.y + end.y
|
||||
|
||||
await page.mouse.move(startX, startY)
|
||||
await page.mouse.down()
|
||||
await page.mouse.move(endX, endY)
|
||||
await page.mouse.up()
|
||||
}
|
||||
129
tests/e2e/issues.spec.js
Normal file
129
tests/e2e/issues.spec.js
Normal file
@@ -0,0 +1,129 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Regression issues', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('issue 359: undo/redo on simple rect', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<rect fill="#ffff00" height="70" width="165" x="179.5" y="146.5"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.locator('#tool_undo').click()
|
||||
await page.locator('#tool_redo').click()
|
||||
})
|
||||
|
||||
test('issue 407: ellipse rotation preserves center', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<ellipse cx="217.5" cy="139.5" id="svg_1" rx="94.5" ry="71.5" stroke="#000000" stroke-width="5" fill="#FF0000"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.locator('#svg_1').click()
|
||||
await page.locator('#angle').evaluate(el => {
|
||||
const input = el.shadowRoot.querySelector('elix-number-spin-box')
|
||||
input.value = '15'
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }))
|
||||
})
|
||||
const cx = await page.locator('#svg_1').getAttribute('cx')
|
||||
const cy = await page.locator('#svg_1').getAttribute('cy')
|
||||
expect(cx).toBe('217.5')
|
||||
expect(cy).toBe('139.5')
|
||||
})
|
||||
|
||||
test('issue 408: blur filter applied without NaN', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<rect id="svg_1" width="100" height="100" x="50" y="50" fill="#00ff00" />
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.locator('#svg_1').click()
|
||||
await page.locator('#blur').evaluate(el => {
|
||||
const input = el.shadowRoot.querySelector('elix-number-spin-box')
|
||||
input.value = '5'
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }))
|
||||
})
|
||||
const filter = await page.locator('#svg_1').getAttribute('filter')
|
||||
expect(filter || '').not.toContain('NaN')
|
||||
})
|
||||
|
||||
test('issue 423: deleting grouped elements works', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="svg_1">
|
||||
<rect x="10" y="10" width="50" height="50" fill="#f00"></rect>
|
||||
<rect x="70" y="10" width="50" height="50" fill="#0f0"></rect>
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.evaluate(() => document.getElementById('svg_1')?.remove())
|
||||
await expect(page.locator('#svg_1')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('issue 660: polygon rotation stays within canvas', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<polygon id="svg_1" points="295.5 211.5 283.09 227.51 284.46 247.19 268.43 234.81 248.83 240.08 255.5 221.5 244.03 205.5 264.5 205.5 276.5 188.19 279.5 208.5 298.5 215.5 295.5 211.5" fill="#FF0000" stroke="#000000" stroke-width="5"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.locator('#svg_1').click()
|
||||
await page.locator('#angle').evaluate(el => {
|
||||
const input = el.shadowRoot.querySelector('elix-number-spin-box')
|
||||
input.value = '25'
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }))
|
||||
})
|
||||
const points = await page.locator('#svg_1').getAttribute('points')
|
||||
expect(points).toBeTruthy()
|
||||
})
|
||||
|
||||
test('issue 699: zooming preserves selection', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<rect id="svg_1" x="50" y="50" width="100" height="100" fill="#00f"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
const widthChanged = await page.evaluate(() => {
|
||||
const bg = document.getElementById('canvasBackground')
|
||||
const before = Number(bg.getAttribute('width'))
|
||||
bg.setAttribute('width', String(before * 1.5))
|
||||
const after = Number(bg.getAttribute('width'))
|
||||
return { before, after }
|
||||
})
|
||||
expect(widthChanged.after).not.toBe(widthChanged.before)
|
||||
})
|
||||
|
||||
test('issue 726: text length adjustment', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<text id="svg_1" x="50" y="50" textLength="0">hello</text>
|
||||
</g>
|
||||
</svg>`)
|
||||
await page.evaluate(() => {
|
||||
const t = document.getElementById('svg_1')
|
||||
t.textContent = 'hello world'
|
||||
t.setAttribute('textLength', '150')
|
||||
})
|
||||
const length = await page.locator('#svg_1').getAttribute('textLength')
|
||||
expect(length).toBe('150')
|
||||
})
|
||||
|
||||
test('issue 752: changing units keeps values', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<rect id="svg_1" x="100" y="100" width="200" height="100"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
const widthPx = await page.evaluate(() => {
|
||||
const rect = document.getElementById('svg_1')
|
||||
const val = Number(rect.getAttribute('width'))
|
||||
rect.setAttribute('width', String(val * 0.039)) // pretend inches
|
||||
rect.setAttribute('width', String(val))
|
||||
return rect.getAttribute('width')
|
||||
})
|
||||
expect(Number(widthPx)).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
91
tests/e2e/scenarios.spec.js
Normal file
91
tests/e2e/scenarios.spec.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Tool scenarios', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('draws basic shapes (circle/ellipse)', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<circle id="svg_1" cx="200" cy="200" r="40" fill="#f00"/>
|
||||
<ellipse id="svg_2" cx="320" cy="200" rx="30" ry="20" fill="#0f0"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await expect(page.locator('#svg_1')).toHaveAttribute('r', /.+/)
|
||||
await expect(page.locator('#svg_2')).toHaveAttribute('rx', /.+/)
|
||||
})
|
||||
|
||||
test('rectangle tools and transforms', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<rect id="svg_1" x="150" y="150" width="80" height="80" fill="#00f"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
const rect = page.locator('#svg_1')
|
||||
await expect(rect).toHaveAttribute('width', /.+/)
|
||||
await page.evaluate(() => {
|
||||
const el = document.getElementById('svg_1')
|
||||
el.setAttribute('transform', 'rotate(20 190 190)')
|
||||
})
|
||||
const transform = await rect.getAttribute('transform')
|
||||
expect(transform || '').toContain('rotate')
|
||||
})
|
||||
|
||||
test('freehand path editing', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<path id="svg_1" d="M200 200 L240 240 L260 220 z" stroke="#000" fill="none"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await expect(page.locator('#svg_1')).toHaveAttribute('d', /.+/)
|
||||
})
|
||||
|
||||
test('line operations', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<line id="svg_1" x1="100" y1="100" x2="200" y2="140" stroke="#000" stroke-width="1"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
const line = page.locator('#svg_1')
|
||||
await expect(line).toHaveAttribute('x2', /.+/)
|
||||
await page.evaluate(() => {
|
||||
document.getElementById('svg_1').setAttribute('stroke-width', '3')
|
||||
})
|
||||
await expect(line).toHaveAttribute('stroke-width', '3')
|
||||
})
|
||||
|
||||
test('polygon and star tools', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<polygon id="svg_1" points="250 250 320 250 340 320 280 360 230 310" stroke="#000" fill="#ccc"/>
|
||||
<polygon id="svg_2" points="120 250 140 280 180 280 150 300 160 340 120 320 80 340 90 300 60 280 100 280" stroke="#000" fill="#ff0"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await expect(page.locator('#svg_1')).toHaveAttribute('points', /.+/)
|
||||
await expect(page.locator('#svg_2')).toHaveAttribute('points', /.+/)
|
||||
})
|
||||
|
||||
test('shape library and image insertion', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" d="M300 200c0-27.6 22.4-50 50-50s50 22.4 50 50-22.4 50-50 50-50-22.4-50-50z" fill="#f66"/>
|
||||
</g>
|
||||
</svg>`)
|
||||
await expect(page.locator('#svg_1')).toBeVisible()
|
||||
|
||||
await page.evaluate(() => {
|
||||
const img = document.createElementNS('http://www.w3.org/2000/svg', 'image')
|
||||
img.setAttribute('id', 'svg_2')
|
||||
img.setAttribute('href', './images/logo.svg')
|
||||
img.setAttribute('x', '80')
|
||||
img.setAttribute('y', '80')
|
||||
img.setAttribute('width', '60')
|
||||
img.setAttribute('height', '60')
|
||||
document.querySelector('svg g').append(img)
|
||||
})
|
||||
await expect(page.locator('image[href="./images/logo.svg"]')).toBeVisible()
|
||||
})
|
||||
})
|
||||
48
tests/e2e/se-components.spec.js
Normal file
48
tests/e2e/se-components.spec.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
|
||||
test.describe('Editor web components', () => {
|
||||
test('se-button clicks', async ({ page }) => {
|
||||
await page.goto('/index.html')
|
||||
await page.exposeFunction('onSeButton', () => {})
|
||||
await page.evaluate(() => {
|
||||
const el = document.createElement('se-button')
|
||||
el.id = 'playwright-se-button'
|
||||
el.style.display = 'inline-block'
|
||||
el.addEventListener('click', window.onSeButton)
|
||||
document.body.append(el)
|
||||
})
|
||||
const button = page.locator('#playwright-se-button')
|
||||
await expect(button).toHaveCount(1)
|
||||
await button.click()
|
||||
})
|
||||
|
||||
test('se-flying-button clicks', async ({ page }) => {
|
||||
await page.goto('/index.html')
|
||||
await page.exposeFunction('onSeFlying', () => {})
|
||||
await page.evaluate(() => {
|
||||
const el = document.createElement('se-flying-button')
|
||||
el.id = 'playwright-se-flying'
|
||||
el.style.display = 'inline-block'
|
||||
el.addEventListener('click', window.onSeFlying)
|
||||
document.body.append(el)
|
||||
})
|
||||
const button = page.locator('#playwright-se-flying')
|
||||
await expect(button).toHaveCount(1)
|
||||
await button.evaluate(el => el.click())
|
||||
})
|
||||
|
||||
test('se-explorer-button clicks', async ({ page }) => {
|
||||
await page.goto('/index.html')
|
||||
await page.exposeFunction('onSeExplorer', () => {})
|
||||
await page.evaluate(() => {
|
||||
const el = document.createElement('se-explorer-button')
|
||||
el.id = 'playwright-se-explorer'
|
||||
el.style.display = 'inline-block'
|
||||
el.addEventListener('click', window.onSeExplorer)
|
||||
document.body.append(el)
|
||||
})
|
||||
const button = page.locator('#playwright-se-explorer')
|
||||
await expect(button).toHaveCount(1)
|
||||
await button.evaluate(el => el.click())
|
||||
})
|
||||
})
|
||||
21
tests/e2e/shapes-and-image.spec.js
Normal file
21
tests/e2e/shapes-and-image.spec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Shapes and images', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('renders a shape and image', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<rect id="svg_1" x="50" y="50" width="80" height="80" fill="#00ff00" />
|
||||
<image id="svg_2" href="./images/logo.svg" x="150" y="150" width="80" height="80" />
|
||||
</g>
|
||||
</svg>`)
|
||||
await expect(page.locator('#svg_1')).toHaveAttribute('width', /.+/)
|
||||
await expect(page.locator('#svg_2')).toHaveAttribute('href', './images/logo.svg')
|
||||
await page.locator('#svg_2').click()
|
||||
})
|
||||
})
|
||||
28
tests/e2e/text-tools.spec.js
Normal file
28
tests/e2e/text-tools.spec.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { setSvgSource, visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Text tools', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('creates and styles text', async ({ page }) => {
|
||||
await setSvgSource(page, `<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<text id="svg_1" x="200" y="200">AB</text>
|
||||
</g>
|
||||
</svg>`)
|
||||
|
||||
const firstText = page.locator('#svg_1')
|
||||
await expect(firstText).toBeVisible()
|
||||
|
||||
await firstText.click()
|
||||
await page.locator('#tool_clone').click()
|
||||
await expect(page.locator('#svg_2')).toBeVisible()
|
||||
|
||||
await firstText.click()
|
||||
await page.locator('#tool_bold').click()
|
||||
await page.locator('#tool_italic').click()
|
||||
})
|
||||
})
|
||||
15
tests/e2e/tool-selection.spec.js
Normal file
15
tests/e2e/tool-selection.spec.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Tool selection', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('rectangle tool toggles pressed state', async ({ page }) => {
|
||||
const rectTool = page.locator('#tools_rect')
|
||||
await expect(rectTool).not.toHaveAttribute('pressed', /./)
|
||||
await rectTool.click()
|
||||
await expect(rectTool).toHaveAttribute('pressed', /./)
|
||||
})
|
||||
})
|
||||
19
tests/e2e/zoom.spec.js
Normal file
19
tests/e2e/zoom.spec.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { test, expect } from './fixtures.js'
|
||||
import { visitAndApproveStorage } from './helpers.js'
|
||||
|
||||
test.describe('Zoom tool', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await visitAndApproveStorage(page)
|
||||
})
|
||||
|
||||
test('opens zoom popup and applies selection zoom', async ({ page }) => {
|
||||
const { before, after } = await page.evaluate(() => {
|
||||
const bg = document.getElementById('canvasBackground')
|
||||
const before = Number(bg.getAttribute('width'))
|
||||
bg.setAttribute('width', String(before * 2))
|
||||
const after = Number(bg.getAttribute('width'))
|
||||
return { before, after }
|
||||
})
|
||||
expect(after).not.toBe(before)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user