feat: rebrand Hemmelig to paste.es for cloudhost.es
- Set Spanish as default language with ephemeral/encrypted privacy focus - Translate all user-facing strings and legal pages to Spanish - Replace Norwegian flag with Spanish flag in footer - Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship - Rewrite PrivacyPage: zero data collection, ephemeral design emphasis - Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references - Update PWA manifest, HTML meta tags, package.json branding - Rename webhook headers to X-Paste-Event / X-Paste-Signature - Update API docs title and contact to paste.es / cloudhost.es Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
189
tests/e2e/secret.spec.ts
Normal file
189
tests/e2e/secret.spec.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
import { expect, test } from './fixtures';
|
||||
|
||||
test.describe('Secret Creation and Viewing', () => {
|
||||
test('should create a secret and display the secret URL', async ({
|
||||
authenticatedPage: page,
|
||||
}) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Type secret content in the editor
|
||||
const editor = page.locator('.ProseMirror');
|
||||
await editor.click();
|
||||
await editor.fill('This is my test secret message');
|
||||
|
||||
// Click create button
|
||||
await page
|
||||
.getByRole('button', { name: /create/i })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// Wait for success state - check for the success icon or URL field
|
||||
await expect(page.getByText(/secret.*created/i)).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify the secret URL is displayed
|
||||
const urlInput = page.locator('input[readonly]').first();
|
||||
await expect(urlInput).toBeVisible();
|
||||
|
||||
const secretUrl = await urlInput.inputValue();
|
||||
expect(secretUrl).toContain('/secret/');
|
||||
expect(secretUrl).toContain('#decryptionKey=');
|
||||
});
|
||||
|
||||
test('should create a secret with a title', async ({ authenticatedPage: page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Type secret content
|
||||
const editor = page.locator('.ProseMirror');
|
||||
await editor.click();
|
||||
await editor.fill('Secret with a title');
|
||||
|
||||
// Add a title
|
||||
const titleInput = page.getByPlaceholder(/title/i);
|
||||
if (await titleInput.isVisible()) {
|
||||
await titleInput.fill('My Secret Title');
|
||||
}
|
||||
|
||||
// Create the secret
|
||||
await page
|
||||
.getByRole('button', { name: /create/i })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// Verify success
|
||||
await expect(page.getByText(/secret.*created/i)).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test('should create and view a secret end-to-end', async ({ authenticatedPage: page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const secretText = `Test secret created at ${Date.now()}`;
|
||||
|
||||
// Create a secret
|
||||
const editor = page.locator('.ProseMirror');
|
||||
await editor.click();
|
||||
await editor.fill(secretText);
|
||||
|
||||
await page
|
||||
.getByRole('button', { name: /create/i })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// Wait for the URL to appear
|
||||
await expect(page.getByText(/secret.*created/i)).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Get the secret URL
|
||||
const urlInput = page.locator('input[readonly]').first();
|
||||
const secretUrl = await urlInput.inputValue();
|
||||
|
||||
// Navigate to the secret URL
|
||||
await page.goto(secretUrl);
|
||||
|
||||
// Click the unlock/view button
|
||||
const unlockButton = page.getByRole('button', { name: /unlock|view/i });
|
||||
await expect(unlockButton).toBeVisible({ timeout: 5000 });
|
||||
await unlockButton.click();
|
||||
|
||||
// Verify the secret content is displayed
|
||||
await expect(page.locator('.ProseMirror')).toContainText(secretText, { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('should create a password-protected secret', async ({ authenticatedPage: page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const secretText = 'This is a password protected secret';
|
||||
const password = 'mysecretpassword123';
|
||||
|
||||
// Type secret content
|
||||
const editor = page.locator('.ProseMirror');
|
||||
await editor.click();
|
||||
await editor.fill(secretText);
|
||||
|
||||
// Look for password protection toggle in security settings section
|
||||
// The toggle might be in a section that needs to be scrolled to
|
||||
const passwordSection = page.locator('text=Password Protection');
|
||||
|
||||
if (await passwordSection.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
// Click the toggle switch near "Password Protection"
|
||||
const toggleSwitch = passwordSection
|
||||
.locator('xpath=..')
|
||||
.locator('button[role="switch"], input[type="checkbox"]');
|
||||
if (await toggleSwitch.isVisible()) {
|
||||
await toggleSwitch.click();
|
||||
|
||||
// Wait for password input to appear
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Find the password input that appeared
|
||||
const passwordInput = page
|
||||
.locator('input[placeholder*="password" i], input[type="password"]')
|
||||
.first();
|
||||
if (await passwordInput.isVisible()) {
|
||||
await passwordInput.fill(password);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Password protection not available, skip this assertion
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the secret
|
||||
await page
|
||||
.getByRole('button', { name: /create/i })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// Wait for success
|
||||
await expect(page.getByText(/secret.*created/i)).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Get the secret URL
|
||||
const urlInput = page.locator('input[readonly]').first();
|
||||
const secretUrl = await urlInput.inputValue();
|
||||
|
||||
// Navigate to the secret
|
||||
await page.goto(secretUrl);
|
||||
|
||||
// If password was set, the secret page should prompt for password
|
||||
// (URL might still have decryptionKey depending on implementation)
|
||||
const unlockButton = page.getByRole('button', { name: /unlock|view/i });
|
||||
await expect(unlockButton).toBeVisible({ timeout: 5000 });
|
||||
await unlockButton.click();
|
||||
|
||||
// Verify content is visible (secret should decrypt with the key in URL)
|
||||
await expect(page.locator('.ProseMirror')).toContainText(secretText, { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('should burn a secret after viewing', async ({ authenticatedPage: page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// Create a secret
|
||||
const editor = page.locator('.ProseMirror');
|
||||
await editor.click();
|
||||
await editor.fill('Secret to be burned');
|
||||
|
||||
await page
|
||||
.getByRole('button', { name: /create/i })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
// Wait for success and get URL
|
||||
await expect(page.getByText(/secret.*created/i)).toBeVisible({ timeout: 10000 });
|
||||
const urlInput = page.locator('input[readonly]').first();
|
||||
const secretUrl = await urlInput.inputValue();
|
||||
|
||||
// View the secret
|
||||
await page.goto(secretUrl);
|
||||
await page.getByRole('button', { name: /unlock|view/i }).click();
|
||||
await expect(page.locator('.ProseMirror')).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Delete the secret
|
||||
await page.getByRole('button', { name: /delete/i }).click();
|
||||
|
||||
// Confirm deletion in modal
|
||||
const confirmButton = page.getByRole('button', { name: /delete|confirm/i }).last();
|
||||
await confirmButton.click();
|
||||
|
||||
// Should redirect to home
|
||||
await expect(page).toHaveURL('/');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user