Skip to content

Commit 24571b2

Browse files
JohnMcLearclaude
andcommitted
fix(i18n): describe session transfer as a one-time code, not a link (#8173)
The home-page settings dialog told users to copy and open a "link" to transfer their "session", but the flow copies a bare one-time UUID that has to be pasted into the Receive session tab, and only moves the author token and pad preferences (not a login/Express session). Update the English copy of the existing keys to describe the real code-based workflow, its single-use/5-minute lifetime, and exactly what is moved. Add a Playwright spec asserting the rendered strings. Fixes #8173 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012kA75NPq8nGRidAwhPXeCi
1 parent f95d67b commit 24571b2

2 files changed

Lines changed: 65 additions & 9 deletions

File tree

src/locales/en.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,16 @@
219219
"index.settings": "Settings",
220220
"index.transferSessionTitle": "Transfer session",
221221
"index.receiveSessionTitle": "Receive session",
222-
"index.receiveSessionDescription": "Here you can receive an Etherpad session from another browser or device. Please note, however, that this will delete your current session, if any.",
223-
"index.transferSession": "1. Transfer session",
224-
"index.transferSessionNow": "Transfer session now",
225-
"index.copyLink": "2. Copy link",
226-
"index.copyLinkDescription": "Click on the button below to copy the link to your clipboard.",
227-
"index.copyLinkButton": "Copy link to clipboard",
228-
"index.transferToSystem": "3. Copy session to new system",
229-
"index.transferToSystemDescription": "Open the copied link in the target browser or device to transfer your session.",
222+
"index.receiveSessionDescription": "Here you can receive your Etherpad author identity and preferences from another browser or device. Please note that this replaces the author identity currently used in this browser, if any.",
223+
"index.transferSession": "1. Create a transfer code",
224+
"index.transferSessionNow": "Create transfer code",
225+
"index.copyLink": "2. Copy the transfer code",
226+
"index.copyLinkDescription": "Click on the button below to copy the transfer code to your clipboard. The code can only be used once and expires after 5 minutes.",
227+
"index.copyLinkButton": "Copy code to clipboard",
228+
"index.transferToSystem": "3. Paste the transfer code",
229+
"index.transferToSystemDescription": "Paste the transfer code you copied on the other browser or device into the field below.",
230230
"index.code": "Code",
231-
"index.transferSessionDescription": "Transfer your current session to browser or device by clicking the button below. This will copy a link to a page that will transfer your session when opened in the target browser or device.",
231+
"index.transferSessionDescription": "Move your Etherpad author identity (so your edits stay attributed to you) and your preferences to another browser or device. Click the button below to create a one-time transfer code, then paste the code into the receiving browser or device. Other data, such as sign-in sessions, is not transferred.",
232232
"index.createOpenPad": "Open pad by name",
233233
"index.openPad": "open an existing Pad with the name:",
234234
"index.recentPads": "Recent Pads",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {expect, test} from '@playwright/test';
2+
3+
// ether/etherpad#8173: the session transfer dialog used to tell users to
4+
// copy and open a "link", but the flow actually copies a one-time code that
5+
// has to be pasted into the "Receive session" tab of the other browser, and
6+
// it only moves the author identity and preferences, not a full login
7+
// session. These assertions check the rendered (localized) English copy
8+
// matches that behaviour.
9+
test.describe('session transfer dialog copy', () => {
10+
test.beforeEach(async ({page}) => {
11+
await page.goto('http://localhost:9001/?lang=en');
12+
await page.locator('.settings-button').click();
13+
await expect(page.locator('#settings-dialog')).toBeVisible();
14+
});
15+
16+
test('transfer tab describes a code, not a link', async ({page}) => {
17+
const description = page.locator('[data-l10n-id="index.transferSessionDescription"]');
18+
await expect(description).toContainText('code');
19+
await expect(description).toContainText('author identity');
20+
await expect(description).not.toContainText('link');
21+
22+
await expect(page.locator('[data-l10n-id="index.transferSessionNow"]'))
23+
.toHaveText('Create transfer code');
24+
25+
await page.route('**/tokenTransfer', (route) => route.fulfill({
26+
status: 200,
27+
contentType: 'application/json',
28+
body: JSON.stringify({id: '12345678-1234-5678-1234-567812345678'}),
29+
}));
30+
await page.locator('[data-l10n-id="index.transferSessionNow"]').click();
31+
32+
const copySection = page.locator('#copy-link-section');
33+
await expect(copySection).toBeVisible();
34+
await expect(copySection.locator('[data-l10n-id="index.copyLink"]'))
35+
.toHaveText('2. Copy the transfer code');
36+
await expect(copySection.locator('[data-l10n-id="index.copyLinkDescription"]'))
37+
.not.toContainText('link');
38+
await expect(copySection.locator('[data-l10n-id="index.copyLinkButton"]'))
39+
.toHaveText('Copy code to clipboard');
40+
});
41+
42+
test('receive tab asks for the code to be pasted', async ({page}) => {
43+
await page.locator('#button-bar button[data-l10n-id="index.receiveSessionTitle"]').click();
44+
const receiveSection = page.locator('#transfer-to-system-section');
45+
await expect(receiveSection).toBeVisible();
46+
await expect(receiveSection.locator('[data-l10n-id="index.transferToSystem"]'))
47+
.toHaveText('3. Paste the transfer code');
48+
const description =
49+
receiveSection.locator('[data-l10n-id="index.transferToSystemDescription"]');
50+
await expect(description).toContainText('Paste');
51+
await expect(description).not.toContainText('link');
52+
await expect(receiveSection.locator('[data-l10n-id="index.receiveSessionDescription"]'))
53+
.toContainText('author identity');
54+
await expect(receiveSection.locator('#codeInput')).toBeVisible();
55+
});
56+
});

0 commit comments

Comments
 (0)