mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-13 07:35:33 +03:00
fix: filechooser interception in OOPIFs (#14432)
This commit is contained in:
parent
962d933c78
commit
abced7223c
@ -219,8 +219,8 @@ export class CRPage implements PageDelegate {
|
||||
await this._forAllFrameSessions(frame => frame._updateRequestInterception());
|
||||
}
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean) {
|
||||
await this._forAllFrameSessions(frame => frame.setFileChooserIntercepted(enabled));
|
||||
async updateFileChooserInterception() {
|
||||
await this._forAllFrameSessions(frame => frame._updateFileChooserInterception(false));
|
||||
}
|
||||
|
||||
async reload(): Promise<void> {
|
||||
@ -559,6 +559,7 @@ class FrameSession {
|
||||
promises.push(this._updateOffline(true));
|
||||
promises.push(this._updateHttpCredentials(true));
|
||||
promises.push(this._updateEmulateMedia(true));
|
||||
promises.push(this._updateFileChooserInterception(true));
|
||||
for (const binding of this._crPage._page.allBindings())
|
||||
promises.push(this._initBinding(binding));
|
||||
for (const source of this._crPage._browserContext.initScripts)
|
||||
@ -1082,7 +1083,10 @@ class FrameSession {
|
||||
await this._networkManager.setRequestInterception(this._page._needsRequestInterception());
|
||||
}
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean) {
|
||||
async _updateFileChooserInterception(initial: boolean) {
|
||||
const enabled = this._page._state.interceptFileChooser;
|
||||
if (initial && !enabled)
|
||||
return;
|
||||
await this._client.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ export class FFPage implements PageDelegate {
|
||||
await this._networkManager.setRequestInterception(this._page._needsRequestInterception());
|
||||
}
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean) {
|
||||
async updateFileChooserInterception(enabled: boolean) {
|
||||
await this._session.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ export interface PageDelegate {
|
||||
setEmulatedSize(emulatedSize: types.EmulatedSize): Promise<void>;
|
||||
updateEmulateMedia(): Promise<void>;
|
||||
updateRequestInterception(): Promise<void>;
|
||||
setFileChooserIntercepted(enabled: boolean): Promise<void>;
|
||||
updateFileChooserInterception(enabled: boolean): Promise<void>;
|
||||
bringToFront(): Promise<void>;
|
||||
|
||||
setBackgroundColor(color?: { r: number; g: number; b: number; a: number; }): Promise<void>;
|
||||
@ -104,6 +104,7 @@ type PageState = {
|
||||
reducedMotion: types.ReducedMotion | null;
|
||||
forcedColors: types.ForcedColors | null;
|
||||
extraHTTPHeaders: types.HeadersArray | null;
|
||||
interceptFileChooser: boolean;
|
||||
};
|
||||
|
||||
type ExpectScreenshotOptions = {
|
||||
@ -183,6 +184,7 @@ export class Page extends SdkObject {
|
||||
reducedMotion: browserContext._options.reducedMotion !== undefined ? browserContext._options.reducedMotion : 'no-preference',
|
||||
forcedColors: browserContext._options.forcedColors !== undefined ? browserContext._options.forcedColors : 'none',
|
||||
extraHTTPHeaders: null,
|
||||
interceptFileChooser: false,
|
||||
};
|
||||
this.accessibility = new accessibility.Accessibility(delegate.getAccessibilityTree.bind(delegate));
|
||||
this.keyboard = new input.Keyboard(delegate.rawKeyboard, this);
|
||||
@ -620,7 +622,8 @@ export class Page extends SdkObject {
|
||||
}
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean): Promise<void> {
|
||||
await this._delegate.setFileChooserIntercepted(enabled);
|
||||
this._state.interceptFileChooser = enabled;
|
||||
await this._delegate.updateFileChooserInterception(enabled);
|
||||
}
|
||||
|
||||
frameNavigatedToNewDocument(frame: frames.Frame) {
|
||||
|
@ -77,7 +77,6 @@ export class WKPage implements PageDelegate {
|
||||
private _nextWindowOpenPopupFeatures?: string[];
|
||||
private _recordingVideoFile: string | null = null;
|
||||
private _screencastGeneration: number = 0;
|
||||
private _interceptingFileChooser = false;
|
||||
|
||||
constructor(browserContext: WKBrowserContext, pageProxySession: WKSession, opener: WKPage | null) {
|
||||
this._pageProxySession = pageProxySession;
|
||||
@ -218,7 +217,7 @@ export class WKPage implements PageDelegate {
|
||||
promises.push(session.send('Page.setTimeZone', { timeZone: contextOptions.timezoneId }).
|
||||
catch(e => { throw new Error(`Invalid timezone ID: ${contextOptions.timezoneId}`); }));
|
||||
}
|
||||
if (this._interceptingFileChooser)
|
||||
if (this._page._state.interceptFileChooser)
|
||||
promises.push(session.send('Page.setInterceptFileChooserDialog', { enabled: true }));
|
||||
promises.push(session.send('Page.overrideSetting', { setting: 'DeviceOrientationEventEnabled' as any, value: contextOptions.isMobile }));
|
||||
promises.push(session.send('Page.overrideSetting', { setting: 'FullScreenEnabled' as any, value: !contextOptions.isMobile }));
|
||||
@ -725,8 +724,8 @@ export class WKPage implements PageDelegate {
|
||||
await this._pageProxySession.send('Emulation.setAuthCredentials', { username: credentials.username, password: credentials.password });
|
||||
}
|
||||
|
||||
async setFileChooserIntercepted(enabled: boolean) {
|
||||
this._interceptingFileChooser = enabled;
|
||||
async updateFileChooserInterception() {
|
||||
const enabled = this._page._state.interceptFileChooser;
|
||||
await this._session.send('Page.setInterceptFileChooserDialog', { enabled }).catch(e => {}); // target can be closed.
|
||||
}
|
||||
|
||||
|
@ -311,6 +311,21 @@ it('should allow cdp sessions on oopifs', async function({ page, browser, server
|
||||
expect(JSON.stringify(oopif)).toContain('./digits/1.png');
|
||||
});
|
||||
|
||||
it('should emit filechooser event for iframe', async ({ page, server, browser }) => {
|
||||
// Add listener before OOPIF is created.
|
||||
const chooserPromise = page.waitForEvent('filechooser');
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
expect(page.frames().length).toBe(2);
|
||||
const frame = page.frames()[1];
|
||||
await frame.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
chooserPromise,
|
||||
frame.click('input'),
|
||||
]);
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
async function countOOPIFs(browser) {
|
||||
const browserSession = await browser.newBrowserCDPSession();
|
||||
const oopifs = [];
|
||||
|
@ -517,3 +517,17 @@ it('should emit event after navigation', async ({ page, server, browserName, bro
|
||||
]);
|
||||
expect(logs).toEqual(['filechooser', 'filechooser']);
|
||||
});
|
||||
|
||||
it('should trigger listener added before navigation', async ({ page, server }) => {
|
||||
// Add listener before cross process navigation.
|
||||
const chooserPromise = new Promise(f => page.once('filechooser', f));
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
chooserPromise,
|
||||
page.click('input'),
|
||||
]);
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user