diff --git a/test/cli/file/simple.spec.ts b/test/cli/file/simple.spec.ts new file mode 100644 index 0000000..ac49191 --- /dev/null +++ b/test/cli/file/simple.spec.ts @@ -0,0 +1,33 @@ +import { test } from '@playwright/test' +import { basename } from 'node:path' +import { Files, getFileChecksum, rm, tmpFile } from '../../files' +import { CLI, getLinkFromCLI } from '../../utils' + +test.describe('file @cli', () => { + test('simple', async ({ page }) => { + const file = await tmpFile(Files.Image) + const checksum = await getFileChecksum(file) + const note = await CLI('send', 'file', file) + const link = getLinkFromCLI(note.stdout) + await rm(file) + + await CLI('open', link, '--all') + const c = await getFileChecksum(basename(file)) + await rm(basename(file)) + test.expect(checksum).toBe(c) + }) + + test('simple with password', async ({ page }) => { + const file = await tmpFile(Files.Image) + const password = 'password' + const checksum = await getFileChecksum(file) + const note = await CLI('send', 'file', file, '--password', password) + const link = getLinkFromCLI(note.stdout) + await rm(file) + + await CLI('open', link, '--all', '--password', password) + const c = await getFileChecksum(basename(file)) + await rm(basename(file)) + test.expect(checksum).toBe(c) + }) +}) diff --git a/test/cli/text/simple.spec.ts b/test/cli/text/simple.spec.ts index 0434f25..6286b4b 100644 --- a/test/cli/text/simple.spec.ts +++ b/test/cli/text/simple.spec.ts @@ -1,13 +1,23 @@ import { test } from '@playwright/test' -import { CLI } from '../../utils' +import { CLI, getLinkFromCLI } from '../../utils' test.describe('text @cli', () => { test('simple', async ({ page }) => { const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.` const note = await CLI('send', 'text', text) - const link = note.stdout.trim().replace(/(.|\s)*http/g, 'http') + const link = getLinkFromCLI(note.stdout) const retrieved = await CLI('open', link) test.expect(retrieved.stdout.trim()).toBe(text) }) + + test('simple with password', async ({ page }) => { + const text = `Endless prejudice endless play derive joy eternal-return selfish burying.` + const password = 'password' + const note = await CLI('send', 'text', text, '--password', password) + const link = getLinkFromCLI(note.stdout) + + const retrieved = await CLI('open', link, '--password', password) + test.expect(retrieved.stdout.trim()).toBe(text) + }) }) diff --git a/test/cross/file/simple.spec.ts b/test/cross/file/simple.spec.ts new file mode 100644 index 0000000..103d29c --- /dev/null +++ b/test/cross/file/simple.spec.ts @@ -0,0 +1,53 @@ +import { test } from '@playwright/test' +import { CLI, checkLinkForDownload, checkLinkForText, createNote, getLinkFromCLI } from '../../utils' +import { Files, getFileChecksum, rm, tmpFile } from '../../files' +import { basename } from 'path' + +const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.` +const password = 'password' + +test.describe('text @cross', () => { + test('cli to web', async ({ page }) => { + const file = await tmpFile(Files.Image) + const checksum = await getFileChecksum(file) + const note = await CLI('send', 'file', file) + const link = getLinkFromCLI(note.stdout) + await rm(file) + + await checkLinkForDownload(page, { link, text: basename(file), checksum }) + }) + + test('cli to web with password', async ({ page }) => { + const file = await tmpFile(Files.Image) + const checksum = await getFileChecksum(file) + const note = await CLI('send', 'file', file, '--password', password) + const link = getLinkFromCLI(note.stdout) + await rm(file) + + await checkLinkForDownload(page, { link, text: basename(file), checksum, password }) + }) + + test('web to cli', async ({ page }) => { + const files = [Files.Image] + const checksum = await getFileChecksum(files[0]) + const link = await createNote(page, { files }) + + const filename = basename(files[0]) + await CLI('open', link, '--all') + const c = await getFileChecksum(filename) + await rm(basename(filename)) + test.expect(checksum).toBe(c) + }) + + test('web to cli with password', async ({ page }) => { + const files = [Files.Image] + const checksum = await getFileChecksum(files[0]) + const link = await createNote(page, { files, password }) + + const filename = basename(files[0]) + await CLI('open', link, '--all', '--password', password) + const c = await getFileChecksum(filename) + await rm(basename(filename)) + test.expect(checksum).toBe(c) + }) +}) diff --git a/test/cross/text/simple.spec.ts b/test/cross/text/simple.spec.ts index 676c0c0..02f52e6 100644 --- a/test/cross/text/simple.spec.ts +++ b/test/cross/text/simple.spec.ts @@ -1,14 +1,15 @@ import { test } from '@playwright/test' -import { CLI, checkLinkForText, createNote } from '../../utils' +import { CLI, checkLinkForText, createNote, getLinkFromCLI } from '../../utils' const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.` +const password = 'password' test.describe('text @cross', () => { test('cli to web', async ({ page }) => { const note = await CLI('send', 'text', text) - const link = note.stdout.trim().replace(/(.|\s)*http/g, 'http') + const link = getLinkFromCLI(note.stdout) - await checkLinkForText(page, link, text) + await checkLinkForText(page, { link, text }) }) test('web to cli', async ({ page }) => { @@ -16,4 +17,16 @@ test.describe('text @cross', () => { const retrieved = await CLI('open', link) test.expect(retrieved.stdout.trim()).toBe(text) }) + + test('cli to web with password', async ({ page }) => { + const note = await CLI('send', 'text', text, '--password', password) + const link = getLinkFromCLI(note.stdout) + await checkLinkForText(page, { link, text, password }) + }) + + test('web to cli with password', async ({ page }) => { + const link = await createNote(page, { text, password }) + const retrieved = await CLI('open', link, '--password', password) + test.expect(retrieved.stdout.trim()).toBe(text) + }) }) diff --git a/test/files.ts b/test/files.ts new file mode 100644 index 0000000..4ef84e0 --- /dev/null +++ b/test/files.ts @@ -0,0 +1,25 @@ +import { createHash } from 'crypto' +import { cp as cpFN, rm as rmFN } from 'fs' +import { readFile } from 'fs/promises' +import { promisify } from 'util' + +export const cp = promisify(cpFN) +export const rm = promisify(rmFN) + +export const Files = { + PDF: 'test/assets/AES.pdf', + Image: 'test/assets/image.jpg', + Zip: 'test/assets/Pigeons.zip', +} + +export async function getFileChecksum(file: string) { + const buffer = await readFile(file) + const hash = createHash('sha3-256').update(buffer).digest('hex') + return hash +} + +export async function tmpFile(file: string) { + const name = `./tmp/${Math.random().toString(36).substring(7)}` + await cp(file, name) + return name +} diff --git a/test/utils.ts b/test/utils.ts index 99d01d8..d8c3846 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,19 +1,25 @@ import { expect, type Page } from '@playwright/test' -import { createHash } from 'crypto' -import { readFile } from 'fs/promises' import { execFile } from 'node:child_process' import { promisify } from 'node:util' +import { getFileChecksum } from './files' const exec = promisify(execFile) -type CreatePage = { text?: string; files?: string[]; views?: number; expiration?: number; error?: string } +type CreatePage = { + text?: string + files?: string[] + views?: number + expiration?: number + error?: string + password?: string +} export async function createNote(page: Page, options: CreatePage): Promise { await page.goto('/') if (options.text) { - await page.locator('[data-testid="text-field"]').fill(options.text) + await page.getByTestId('text-field').fill(options.text) } else if (options.files) { - await page.locator('[data-testid="switch-file"]').click() + await page.getByTestId('switch-file').click() const [fileChooser] = await Promise.all([ page.waitForEvent('filechooser'), @@ -22,13 +28,16 @@ export async function createNote(page: Page, options: CreatePage): Promise> text=${text}`).click(), + page.getByTestId(`result`).locator(`text=${options.text}`).click(), ]) const path = await download.path() if (!path) throw new Error('Download failed') const cs = await getFileChecksum(path) - await expect(cs).toBe(checksum) + await expect(cs).toBe(options.checksum) } -export async function checkLinkForText(page: Page, link: string, text: string) { + +export async function checkLinkForText(page: Page, options: CheckLinkBase) { await page.goto('/') - await page.goto(link) - await page.locator('[data-testid="show-note-button"]').click() - await expect(await page.locator('[data-testid="result"] >> .note').innerText()).toContain(text) + await page.goto(options.link) + if (options.password) await page.getByTestId('show-note-password').fill(options.password) + await page.getByTestId('show-note-button').click() + const text = await page.getByTestId('result').locator('.note').innerText() + await expect(text).toContain(options.text) } export async function checkLinkDoesNotExist(page: Page, link: string) { @@ -68,12 +87,6 @@ export async function checkLinkDoesNotExist(page: Page, link: string) { await expect(page.locator('main')).toContainText('note was not found or was already deleted') } -export async function getFileChecksum(file: string) { - const buffer = await readFile(file) - const hash = createHash('sha3-256').update(buffer).digest('hex') - return hash -} - export async function CLI(...args: string[]) { return await exec('./packages/cli/dist/index.cjs', args, { env: { @@ -82,3 +95,9 @@ export async function CLI(...args: string[]) { }, }) } + +export function getLinkFromCLI(output: string): string { + const match = output.match(/(https?:\/\/[^\s]+)/) + if (!match) throw new Error('No link found in CLI output') + return match[0] +} diff --git a/test/web/file/files.ts b/test/web/file/files.ts deleted file mode 100644 index 6f99fe9..0000000 --- a/test/web/file/files.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - PDF: 'test/assets/AES.pdf', - Image: 'test/assets/image.jpg', - Zip: 'test/assets/Pigeons.zip', -} diff --git a/test/web/file/multiple.spec.ts b/test/web/file/multiple.spec.ts index d3082fe..fea086d 100644 --- a/test/web/file/multiple.spec.ts +++ b/test/web/file/multiple.spec.ts @@ -1,13 +1,13 @@ import { test } from '@playwright/test' -import { checkLinkForDownload, createNote, getFileChecksum } from '../../utils' -import Files from './files' +import { Files, getFileChecksum } from '../../files' +import { checkLinkForDownload, createNote } from '../../utils' test.describe('@web', () => { test('multiple', async ({ page }) => { const files = [Files.PDF, Files.Image] const checksums = await Promise.all(files.map(getFileChecksum)) const link = await createNote(page, { files, views: 2 }) - await checkLinkForDownload(page, link, 'image.jpg', checksums[1]) - await checkLinkForDownload(page, link, 'AES.pdf', checksums[0]) + await checkLinkForDownload(page, { link, text: 'image.jpg', checksum: checksums[1] }) + await checkLinkForDownload(page, { link, text: 'AES.pdf', checksum: checksums[0] }) }) }) diff --git a/test/web/file/simple.spec.ts b/test/web/file/simple.spec.ts index 35fd5c7..00a600d 100644 --- a/test/web/file/simple.spec.ts +++ b/test/web/file/simple.spec.ts @@ -1,12 +1,12 @@ import { test } from '@playwright/test' -import { checkLinkDoesNotExist, checkLinkForDownload, checkLinkForText, createNote, getFileChecksum } from '../../utils' -import Files from './files' +import { Files, getFileChecksum } from '../../files' +import { checkLinkDoesNotExist, checkLinkForDownload, checkLinkForText, createNote } from '../../utils' test.describe('@web', () => { test('simple pdf', async ({ page }) => { const files = [Files.PDF] const link = await createNote(page, { files }) - await checkLinkForText(page, link, 'AES.pdf') + await checkLinkForText(page, { link, text: 'AES.pdf' }) await checkLinkDoesNotExist(page, link) }) @@ -14,13 +14,21 @@ test.describe('@web', () => { const files = [Files.PDF] const checksum = await getFileChecksum(files[0]) const link = await createNote(page, { files }) - await checkLinkForDownload(page, link, 'AES.pdf', checksum) + await checkLinkForDownload(page, { link, text: 'AES.pdf', checksum }) }) test('image content', async ({ page }) => { const files = [Files.Image] const checksum = await getFileChecksum(files[0]) const link = await createNote(page, { files }) - await checkLinkForDownload(page, link, 'image.jpg', checksum) + await checkLinkForDownload(page, { link, text: 'image.jpg', checksum }) + }) + + test('simple pdf with password', async ({ page }) => { + const files = [Files.PDF] + const password = 'password' + const link = await createNote(page, { files, password }) + await checkLinkForText(page, { link, text: 'AES.pdf', password }) + await checkLinkDoesNotExist(page, link) }) }) diff --git a/test/web/file/too-big.spec.ts b/test/web/file/too-big.spec.ts index c2f4794..03ceec6 100644 --- a/test/web/file/too-big.spec.ts +++ b/test/web/file/too-big.spec.ts @@ -1,6 +1,6 @@ import { test } from '@playwright/test' import { createNote } from '../../utils' -import Files from './files' +import { Files } from '../../files' test.describe('@web', () => { test.skip('to big zip', async ({ page }) => { diff --git a/test/web/text/expiration.spec.ts b/test/web/text/expiration.spec.ts index 44a6b24..6ff3e4d 100644 --- a/test/web/text/expiration.spec.ts +++ b/test/web/text/expiration.spec.ts @@ -7,10 +7,10 @@ test.describe('@web', () => { const minutes = 1 const timeout = minutes * 60_000 test.setTimeout(timeout * 2) - const shareLink = await createNote(page, { text, expiration: minutes }) - await checkLinkForText(page, shareLink, text) - await checkLinkForText(page, shareLink, text) + const link = await createNote(page, { text, expiration: minutes }) + await checkLinkForText(page, { link, text }) + await checkLinkForText(page, { link, text }) await page.waitForTimeout(timeout) - await checkLinkDoesNotExist(page, shareLink) + await checkLinkDoesNotExist(page, link) }) }) diff --git a/test/web/text/simple.spec.ts b/test/web/text/simple.spec.ts index a26f5db..ef144c2 100644 --- a/test/web/text/simple.spec.ts +++ b/test/web/text/simple.spec.ts @@ -3,8 +3,15 @@ import { checkLinkForText, createNote } from '../../utils' test.describe('@web', () => { test('simple', async ({ page }) => { - const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.` - const shareLink = await createNote(page, { text }) - await checkLinkForText(page, shareLink, text) + const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of deceive play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.` + const link = await createNote(page, { text }) + await checkLinkForText(page, { link, text }) + }) + + test('simple with password', async ({ page }) => { + const text = 'Foo bar' + const password = '123' + const shareLink = await createNote(page, { text, password }) + await checkLinkForText(page, { link: shareLink, text, password }) }) }) diff --git a/test/web/text/views.spec.ts b/test/web/text/views.spec.ts index 524fa5d..48a9c98 100644 --- a/test/web/text/views.spec.ts +++ b/test/web/text/views.spec.ts @@ -4,17 +4,17 @@ import { checkLinkDoesNotExist, checkLinkForText, createNote } from '../../utils test.describe('@web', () => { test('only shown once', async ({ page }) => { const text = `Christian victorious reason suicide dead. Right ultimate gains god hope truth burying selfish society joy. Ultimate.` - const shareLink = await createNote(page, { text }) - await checkLinkForText(page, shareLink, text) - await checkLinkDoesNotExist(page, shareLink) + const link = await createNote(page, { text }) + await checkLinkForText(page, { link, text }) + await checkLinkDoesNotExist(page, link) }) test('view 3 times', async ({ page }) => { const text = `Justice holiest overcome fearful strong ultimate holiest christianity.` - const shareLink = await createNote(page, { text, views: 3 }) - await checkLinkForText(page, shareLink, text) - await checkLinkForText(page, shareLink, text) - await checkLinkForText(page, shareLink, text) - await checkLinkDoesNotExist(page, shareLink) + const link = await createNote(page, { text, views: 3 }) + await checkLinkForText(page, { link, text }) + await checkLinkForText(page, { link, text }) + await checkLinkForText(page, { link, text }) + await checkLinkDoesNotExist(page, link) }) })