Skip to content
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

Incorrect ElementHandle.boundingBox result x and y when element has padding #136

Open
jaydenseric opened this issue Jan 29, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@jaydenseric
Copy link

If you have an element styled so that its bounding box is at viewport coordinates x 0 and y 0:

#target {
  position: fixed;
  left: 0;
  top: 0;
  padding: 20px;
}

The ElementHandle.boundingBox result x and y incorrectly becomes the padding value, in this case 20, when they should be 0.

This is wreaking havoc with attempts to use ElementHandle.screenshot, as the screenshots are shifted off the target element bounding box by the same amount as the element's padding.

@jaydenseric
Copy link
Author

jaydenseric commented Jan 29, 2025

I think instead of result.content this should be result.border, or result.padding:

const { x, y } = getTopLeft(result.content);

Probably result.border is most correct for a screenshot, as you would expect an element's border to be in its screenshot.

@jaydenseric
Copy link
Author

Also, It's probably incorrect to use result.width and result.height, because the actual width and height of the bounds depends on the kind of bounds (e.g. the border bounds) and the dimensions of their coordinates:

width: result.width,
height: result.height,

@jaydenseric
Copy link
Author

Here is a temporary replacement for the buggy method ElementHandle.screenshot:

// Todo: Replace this helper function with the Astral method
// `ElementHandle.screenshot` once these issues are resolved:
// https://github.com/lino-levan/astral/issues/136
// https://github.com/lino-levan/astral/issues/137
/**
 * Scrolls an Astral page element into view and screenshots it.
 * @see https://github.com/lino-levan/astral/blob/348dda34a0abe8c5719349f3a5a3c4d70bf18a31/src/element_handle.ts#L275-L297
 * @see https://github.com/lino-levan/astral/issues/138
 * @param {Page} page Page the element is in.
 * @param {ElementHandle} element Element to screenshot.
 * @param {Omit<ScreenshotOptions, "clip">
 *   & Pick<NonNullable<ScreenshotOptions["clip"]>, "scale">} options Screenshot
 *   options.
 */
async function elementScreenshot(page, element, options) {
  await element.scrollIntoView();

  const boxModel = await element.boxModel();

  if (!boxModel) {
    throw new Error(
      "No bounding box found when trying to screenshot element.",
    );
  }

  return await page.screenshot({
    ...options,
    clip: {
      x: boxModel.border[0].x,
      y: boxModel.border[0].y,
      width: boxModel.border[2].x - boxModel.border[0].x,
      height: boxModel.border[2].y - boxModel.border[0].y,
      scale: options.scale,
    },
  });
}

It also implements the feature request #137 .

Note that this helper function could have less parameters if #138 was actioned.

@lino-levan lino-levan added the bug Something isn't working label Jan 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants