-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: response.text()/.body() triggers remote request for fulfilled 404 #30760
Comments
I was able to reproduce on Chromium, but not on WebKit/Firefox. Looks like a bug. // @ts-check
import http from 'http';
import playwright from 'playwright';
const root = await startLocalServer();
const browser = await playwright.chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
async function handler(response) {
console.log('on response start', response.url());
console.log('on response status text:', response.statusText());
console.log('on response headers:', await response.headersArray());
console.log('on response text:', await response.body()); // <<-- this triggers a remote fetch, regardless. Does not happen when commented out.
console.log('on response headers2:', await response.headersArray()); // Same as before
console.log('on response finish');
}
page.on('response', response => {
handler(response).then(() => console.log('handler completed...'), e => console.log('handler crashed:', e));
});
await page.route('**', async route => {
const request = route.request();
const url = request.url();
if (url === `${root}/main`) {
console.log('Root (remote) response:');
const response = await route.fetch();
return await route.fulfill({ response });
}
console.log('Fail (mock) response:', [url]);
return route.fulfill({
status: 404,
contentType: 'text/plain',
body: 'Not Found! (mocked)',
});
});
await page.goto(`${root}/main`);
await page.waitForLoadState('networkidle');
console.log('Closing page');
await page.close();
async function startLocalServer() {
const PORT = 3022;
const HOST = 'localhost';
// Serve local website
const server = http.createServer((req, res) => {
console.log('server hit:', req.method, req.url);
if (req.url === '/main') {
res.statusCode = 200;
res.setHeader('x-custom', 'stuff');
res.setHeader('Content-Type', 'text/html');
res.end('<body>main response <script src="/fail"></script>');
return;
}
res.statusCode = 404; // Can return any status code here, doesn't matter really
res.setHeader('Content-Type', 'text/html'); // Content type doesn't appear to matter either
res.setHeader('x-custom', 'stuff');
res.end('This response text should not be fetched and/or displayed'); // At least this doesn't show up?
});
await new Promise(resolve => {
server.listen(PORT, HOST, () => {
resolve(undefined);
});
});
return `http://${HOST}:${PORT}`;
} Expected: No getting printed. |
Seems like the fix has not been released yet? @yury-s |
Yes, its 1.45 which is not released yet. You can try https://playwright.dev/docs/canary-releases |
Thanks. I still get this problem even with next version: test.only("addding new members", async ({ page }) => {
const email = "john@tremendous.com";
await mockOrganizationMembers(page, id, email);
await mockOrganizationRoles(page, id);
await page
.waitForResponse("*/**/admin/accounts/organizations/*/roles/")
.then((response) => expect(response.status()).toBe(200));
})
export async function mockOrganizationCancelRewards(page: Page, id: string) {
return await page.route(
`*/**/admin/accounts/organizations/${id}/cancel_rewards/`,
async (route) => {
await route.fulfill({
json: cancelRewardsResponse,
});
}
);
}
export async function mockOrganizationRoles(page: Page, id: string) {
return await page.route(
`*/**/admin/accounts/organizations/*/roles/`,
(route) =>
route.fulfill({
json: organizationRolesResponse,
})
);
} It is pretty flaky, often fails with
We've just started using playwright. Is there something wrong with my implementation? |
I've tried changing everything I could think of. Returning or not the awaited promise. Changing the blob pattern to use or not asterisks, having the promises within an array with Since there are many times on which it works, I guess it's not fundamentally wrong. But maybe I missed some detail. I imagined this bug fix would solve it, since it seems like the problem is that sometimes the request is done to the server, even though it's mocked, but even with the latest alpha, nothing changes, still very flaky. |
@ThiagoMaia1 could you file a new bug please and reference this one? Issue seems different, might be related but we need a reproduction in order to act on it. Thanks for your understanding! |
Version
1.43.1
Steps to reproduce
await page.router()
and intercept this request, mocking it with a 404 throughfulfill()
await response.body()
response.text()
Expected behavior
When I mock a request through
fulfill
I expect the remote not to be hit at all, regardless of what the mock gives it.Actual behavior
Remote server is hit for unknown reasons.
Response appears to be ignored for insofar you can inspect it.
Additional context
Since the problem does not happen for status 200 responses it feels to me like it's somehow due to not expecting the 404 to have body contents? But that's just a guess.
Using
DEBUG=pw:*
does not really give me more information on why it might happen. It does reject invalid status codes returned by the webserver this way, but that does not seem to fail the response similar to how it otherwise would.Environment
and
Minimal test case:
Output:
The text was updated successfully, but these errors were encountered: