fix(export): per-platform polish from the on-device review
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m41s
- TG iOS: the OS share sheet with the fetched file (WKWebView has navigator.share — the долгоживущий debug-overlay Share path proves it). The chooser stays the app modal on this one platform: a native popup callback cannot supply the user activation the sheet needs. TG Android/desktop keep the native popup + downloadFile (verified perfect, untouched). - VK mobile: the PNG now rides VKWebAppDownloadFile like the GCG — the owner-verified path that lands in VK's native share flow; the ShowImages viewer is dropped (its preview offered save only, no share). - VK desktop iframe: both formats are plain anchor downloads (it is an ordinary browser; the viewer/bridge path made no sense there).
This commit is contained in:
@@ -70,6 +70,7 @@ test('inside Telegram the chooser is the native popup and delivery the native do
|
||||
WebApp: {
|
||||
initData: 'query_id=test&user=%7B%22id%22%3A1%7D&auth_date=1&hash=deadbeef',
|
||||
initDataUnsafe: {},
|
||||
platform: 'android',
|
||||
ready() {},
|
||||
expand() {},
|
||||
showPopup(params: { buttons?: { id?: string; type?: string }[] }, cb: (id: string) => void) {
|
||||
@@ -142,6 +143,60 @@ test('a mobile browser gets the OS share sheet with the fetched file', async ({
|
||||
expect(shared.type).toBe('image/png');
|
||||
});
|
||||
|
||||
test('Telegram on iOS keeps the app chooser and opens the OS share sheet', async ({ page }) => {
|
||||
// TG iOS: WKWebView has navigator.share, and the sheet is the preferred delivery — but
|
||||
// it needs the user activation a native-popup callback cannot provide, so the chooser
|
||||
// stays the app modal on this one platform.
|
||||
await page.addInitScript(() => {
|
||||
const shared: { name: string; type: string }[] = [];
|
||||
Object.defineProperty(navigator, 'canShare', { value: () => true, configurable: true });
|
||||
Object.defineProperty(navigator, 'share', {
|
||||
value: async (data: { files?: File[] }) => {
|
||||
for (const f of data.files ?? []) shared.push({ name: f.name, type: f.type });
|
||||
},
|
||||
configurable: true,
|
||||
});
|
||||
(window as unknown as { __shared: typeof shared }).__shared = shared;
|
||||
Object.assign(window, {
|
||||
Telegram: {
|
||||
WebApp: {
|
||||
initData: 'query_id=test&user=%7B%22id%22%3A1%7D&auth_date=1&hash=deadbeef',
|
||||
initDataUnsafe: {},
|
||||
platform: 'ios',
|
||||
ready() {},
|
||||
expand() {},
|
||||
showPopup() {
|
||||
(window as unknown as { __popupCalled?: boolean }).__popupCalled = true;
|
||||
},
|
||||
downloadFile() {
|
||||
(window as unknown as { __downloadCalled?: boolean }).__downloadCalled = true;
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
await routeDl(page);
|
||||
await page.goto('/');
|
||||
await expect(page.getByText('Your turn')).toBeVisible();
|
||||
await page.getByRole('button', { name: /Rick/ }).click();
|
||||
await expect(page.locator('[data-cell]').first()).toBeVisible();
|
||||
await page.locator('.scoreboard').click();
|
||||
await page.getByRole('button', { name: 'Export game' }).click();
|
||||
|
||||
// The app modal opened (both formats) — the native popup was not used…
|
||||
await expect(page.getByRole('button', { name: 'Image (PNG)' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Image (PNG)' }).click();
|
||||
// …and the artifact went to the OS share sheet, not TG's download dialog.
|
||||
await expect
|
||||
.poll(() => page.evaluate(() => (window as unknown as { __shared: unknown[] }).__shared))
|
||||
.toHaveLength(1);
|
||||
const flags = await page.evaluate(() => {
|
||||
const w = window as unknown as { __popupCalled?: boolean; __downloadCalled?: boolean };
|
||||
return { popup: !!w.__popupCalled, download: !!w.__downloadCalled };
|
||||
});
|
||||
expect(flags).toEqual({ popup: false, download: false });
|
||||
});
|
||||
|
||||
test('a legacy Telegram client (no downloadFile) hides the image and copies the GCG', async ({ page }) => {
|
||||
await page.addInitScript(() => {
|
||||
// Headless engines deny the real clipboard; a permissive stub keeps the legacy
|
||||
|
||||
Reference in New Issue
Block a user