|
1 | 1 | import { Snapshot, Context, DiscoveryErrors } from "../types.js";
|
2 |
| -import { scrollToBottomAndBackToTop, getRenderViewports, getRenderViewportsForOptions } from "./utils.js" |
| 2 | +import { scrollToBottomAndBackToTop, getRenderViewports, getRenderViewportsForOptions, validateCoordinates } from "./utils.js" |
3 | 3 | import { chromium, Locator } from "@playwright/test"
|
4 | 4 | import constants from "./constants.js";
|
5 | 5 | import { updateLogContext } from '../lib/logger.js'
|
@@ -126,6 +126,9 @@ export async function prepareSnapshot(snapshot: Snapshot, ctx: Context): Promise
|
126 | 126 | case 'cssSelector':
|
127 | 127 | selectors.push(...value);
|
128 | 128 | break;
|
| 129 | + case 'coordinates': |
| 130 | + selectors.push(...value.map(e => `coordinates=${e}`)); |
| 131 | + break; |
129 | 132 | }
|
130 | 133 | }
|
131 | 134 | }
|
@@ -500,6 +503,9 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
|
500 | 503 | case 'cssSelector':
|
501 | 504 | selectors.push(...value);
|
502 | 505 | break;
|
| 506 | + case 'coordinates': |
| 507 | + selectors.push(...value.map(e => `coordinates=${e}`)); |
| 508 | + break; |
503 | 509 | }
|
504 | 510 | }
|
505 | 511 | }
|
@@ -663,14 +669,58 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
|
663 | 669 | if (!Array.isArray(processedOptions[ignoreOrSelectBoxes][viewportString])) processedOptions[ignoreOrSelectBoxes][viewportString] = []
|
664 | 670 |
|
665 | 671 | for (const selector of selectors) {
|
| 672 | + if (selector.startsWith('coordinates=')) { |
| 673 | + const coordString = selector.replace('coordinates=', ''); |
| 674 | + let pageHeight = height; |
| 675 | + if (viewport.height) { |
| 676 | + pageHeight = viewport.height; |
| 677 | + } |
| 678 | + const validation = validateCoordinates( |
| 679 | + coordString, |
| 680 | + pageHeight, |
| 681 | + viewport.width, |
| 682 | + snapshot.name |
| 683 | + ); |
| 684 | + |
| 685 | + if (!validation.valid) { |
| 686 | + optionWarnings.add(validation.error!); |
| 687 | + continue; |
| 688 | + } |
| 689 | + |
| 690 | + if(renderViewports.length > 1){ |
| 691 | + optionWarnings.add(`for snapshot ${snapshot.name} viewport ${viewportString}, coordinates may not be accurate for multiple viewports`); |
| 692 | + } |
| 693 | + |
| 694 | + |
| 695 | + const coordinateElement = { |
| 696 | + type: 'coordinates', |
| 697 | + ...validation.coords |
| 698 | + }; |
| 699 | + locators.push(coordinateElement as any); |
| 700 | + continue; |
| 701 | + } |
| 702 | + |
666 | 703 | let l = await page.locator(selector).all()
|
667 | 704 | if (l.length === 0) {
|
668 | 705 | optionWarnings.add(`for snapshot ${snapshot.name} viewport ${viewportString}, no element found for selector ${selector}`);
|
669 | 706 | continue;
|
670 | 707 | }
|
671 | 708 | locators.push(...l);
|
672 | 709 | }
|
| 710 | + |
673 | 711 | for (const locator of locators) {
|
| 712 | + if (locator && typeof locator === 'object' && locator.hasOwnProperty('type') && (locator as any).type === 'coordinates') { |
| 713 | + const coordLocator = locator as any; |
| 714 | + const { top, bottom, left, right } = coordLocator; |
| 715 | + processedOptions[ignoreOrSelectBoxes][viewportString].push({ |
| 716 | + left: left, |
| 717 | + top: top, |
| 718 | + right: right, |
| 719 | + bottom: bottom |
| 720 | + }); |
| 721 | + continue; |
| 722 | + } |
| 723 | + |
674 | 724 | let bb = await locator.boundingBox();
|
675 | 725 | if (bb) {
|
676 | 726 | // Calculate top and bottom from the bounding box properties
|
@@ -738,3 +788,5 @@ export default async function processSnapshot(snapshot: Snapshot, ctx: Context):
|
738 | 788 | discoveryErrors: discoveryErrors
|
739 | 789 | }
|
740 | 790 | }
|
| 791 | + |
| 792 | + |
0 commit comments