Closed Dinh246 closed 11 months ago
Could you share a snippet that reproduces the issue so that I did not need to guess the right steps and locators?
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('https://au-ins-quickview.myshopbase.net/collections/all');
await page.locator("footer.footer-section").evaluate(ele =>
ele.scrollIntoView({ behavior: "instant", block: "center" }),
);
await expect(page.locator("[class*=widget_setting_best_seller]")).toBeVisible();
await page.locator("[class*=widget_setting_best_seller]").evaluate(ele =>
ele.scrollIntoView({ behavior: "instant", block: "center" }),
);
await page.locator("[class*=widget_setting_best_seller]").locator("[class^=upsell-widget-product]").filter({ hasText: 'Product B @SB_SF_BUSF_QVA_19' }).hover();
await page.getByRole('button', { name: 'Add to cart' }).first().click();
await page.getByText('View Size Guide').click();
await page.locator(".upsell-select select").selectOption({ label: 'V-neck T-shirt' })
await expect(page.getByText('.qv-size-chart')).toHaveScreenshot();
});
I can share my solution if you interest too
Here is the error I'm getting when I run your script:
> 12 | await page.locator("[class*=widget_setting_best_seller]").locator("[class^=upsell-widget-product]").hover();
Error: locator.hover: Error: strict mode violation: locator('[class*=widget_setting_best_seller]').locator('[class^=upsell-widget-product]') resolved to 6 elements:
1) <div class="upsell-widget-product upsell-relative">…</div> aka locator('div').filter({ hasText: /^Target product @SB_SF_BUSF_QVA_18\$12\.99 USDAdd to cart$/ }).nth(1)
2) <div class="upsell-widget-product upsell-relative">…</div> aka locator('div').filter({ hasText: /^Product cuối\$0\.00 USDAdd to cart$/ }).nth(1)
3) <div class="upsell-widget-product upsell-relative">…</div> aka locator('div').filter({ hasText: /^Recommend product @SB_SF_BUSF_QVA_18\$255\.00 USDAdd to cart$/ }).nth(1)
4) <div class="upsell-widget-product upsell-relative">…</div> aka locator('div').filter({ hasText: /^Product B @SB_SF_BUSF_QVA_19\$33\.99 USD\$48\.99 USDAdd to cart$/ }).nth(1)
5) <div class="upsell-widget-product__original-price ups…>$48.99 USD</div> aka locator('#app_best-seller_1').getByText('$48.99 USD')
6) <div class="upsell-widget-product upsell-relative">…</div> aka locator('div').filter({ hasText: /^Product 8 variants @SB_SF_BUSF_QVA_19\$502\.00 USDAdd to cart$/ }).nth(1)
@pavelfeldman oops sorry I'm missing filter. Edited please copy and run again
~I can't even click add to cart due to the occlusion detection, we'll look into it.~, Ah, that's because you are clicking first()
"Add to cart" and your product could be third. Should be
const productLocator = page.locator('[class*=widget_setting_best_seller]').locator('[class^=upsell-widget-product]').filter({ hasText: 'Product B @SB_SF_BUSF_QVA_19' });
await productLocator.hover();
await productLocator.getByRole('button', { name: 'Add to cart' }).first().click();
but that is beside the topic of the issue.
The remainder of the issue seems to be due to the specificity of the page. We resize viewport momentarily and take a screenshot. And if you do that real quick, that is what we see on the screen. After some time the size chart would resize to take up all the space.
@pavelfeldman I thought about it too and gave it a wait 10s but the result is the same. However, if I resize the viewport to bigger height than the locator I can capture the full screenshot as expected.
@Dinh246 Unfortunately, waiting for any amount of time before the screenshot will not help. The issue is during the screenshot: since your target element is larger than the available viewport, browser temporarily resizes the page to be larger to accommodate the element. When page expects to perform some asynchronous changes upon resize, those changes are not captured on the screenshot.
The workaround would be to manually resize the page beforehand, such that the target element fits the viewport:
await page.setViewportSize({ width: 1280, height: 2000 });
await expect(page.getByText('.qv-size-chart')).toHaveScreenshot();
Let me know whether this helps.
Closing because there is no action item for Playwright. If you still encounter problems, please file a new issue with a repro and link to this one.
System info
Source code
await expect(locator).toHaveScreenshot("expected.png")
Steps
Expected
Should fully capture screenshot of the locator
Actual
Playwright only capture the visible part in viewport, other parts which are hidden to the viewport will be blank. Also if we take screenshot in a popup (same condition locator's height > viewport's height) it will capture a part of the locator that in viewport and the behind part of the page.
Feature request I also figured solution for this by resizing the viewport if height, width of locator > viewport so I request to add an option that check the size of locator and resize the viewport before taking screenshot and change back when finish verify to avoid this bug.