|
1 | | -import { Locator, Page } from "playwright"; |
| 1 | +import { Download, Locator, Page } from "playwright"; |
2 | 2 | import BasePage from "../../infra/ui/basePage"; |
3 | 3 | import { waitForElementToBeVisible, waitForStableText, waitToBeEnabled } from "../utils"; |
4 | 4 |
|
@@ -228,9 +228,13 @@ export default class CodeGraph extends BasePage { |
228 | 228 | private get copyToClipboardNodePanelDetails(): Locator { |
229 | 229 | return this.page.locator(`//div[@data-name='node-details-panel']//button[@title='Copy src to clipboard']`); |
230 | 230 | } |
231 | | - |
232 | | - private get nodeToolTip(): Locator { |
233 | | - return this.page.locator("//div[contains(@class, 'graph-tooltip')]"); |
| 231 | + |
| 232 | + private get nodeToolTip(): (node: string) => Locator { |
| 233 | + return (node: string) => this.page.locator(`//div[contains(@class, 'force-graph-container')]/div[contains(text(), '${node}')]`); |
| 234 | + } |
| 235 | + |
| 236 | + private get downloadImageBtn(): Locator { |
| 237 | + return this.page.locator("//button[@title='downloadImage']"); |
234 | 238 | } |
235 | 239 |
|
236 | 240 | /* NavBar functionality */ |
@@ -423,6 +427,7 @@ export default class CodeGraph extends BasePage { |
423 | 427 | const button = this.searchBarOptionBtn(buttonNum); |
424 | 428 | await button.waitFor({ state : "visible"}) |
425 | 429 | await button.click(); |
| 430 | + await this.page.waitForTimeout(4000); |
426 | 431 | } |
427 | 432 |
|
428 | 433 | async getSearchBarInputValue(): Promise<string> { |
@@ -463,20 +468,20 @@ export default class CodeGraph extends BasePage { |
463 | 468 | } |
464 | 469 |
|
465 | 470 | async nodeClick(x: number, y: number): Promise<void> { |
466 | | - for (let attempt = 1; attempt <= 2; attempt++) { |
| 471 | + for (let attempt = 1; attempt <= 3; attempt++) { |
467 | 472 | await this.canvasElement.hover({ position: { x, y } }); |
468 | 473 | await this.page.waitForTimeout(500); |
469 | | - |
470 | | - if (await waitForElementToBeVisible(this.nodeToolTip)) { |
471 | | - await this.canvasElement.click({ position: { x, y }, button: 'right' }); |
| 474 | + await this.canvasElement.click({ position: { x, y }, button: 'right' }); |
| 475 | + if (await this.elementMenu.isVisible()) { |
472 | 476 | return; |
473 | 477 | } |
474 | 478 | await this.page.waitForTimeout(1000); |
475 | 479 | } |
476 | | - |
477 | | - throw new Error("Tooltip not visible after multiple attempts!"); |
| 480 | + |
| 481 | + throw new Error(`Failed to click, elementMenu not visible after multiple attempts.`); |
478 | 482 | } |
479 | 483 |
|
| 484 | + |
480 | 485 | async selectCodeGraphCheckbox(checkbox: string): Promise<void> { |
481 | 486 | await this.codeGraphCheckbox(checkbox).click(); |
482 | 487 | } |
@@ -637,4 +642,60 @@ export default class CodeGraph extends BasePage { |
637 | 642 | return { scaleX, scaleY }; |
638 | 643 | } |
639 | 644 |
|
| 645 | + async downloadImage(): Promise<Download> { |
| 646 | + await this.page.waitForLoadState('networkidle'); |
| 647 | + const [download] = await Promise.all([ |
| 648 | + this.page.waitForEvent('download'), |
| 649 | + this.downloadImageBtn.click(), |
| 650 | + ]); |
| 651 | + |
| 652 | + return download; |
| 653 | + } |
| 654 | + |
| 655 | + async rightClickAtCanvasCenter(): Promise<void> { |
| 656 | + const boundingBox = await this.canvasElement.boundingBox(); |
| 657 | + if (!boundingBox) throw new Error('Canvas bounding box not found'); |
| 658 | + const centerX = boundingBox.x + boundingBox.width / 2; |
| 659 | + const centerY = boundingBox.y + boundingBox.height / 2; |
| 660 | + await this.page.mouse.click(centerX, centerY, { button: 'right' }); |
| 661 | + } |
| 662 | + |
| 663 | + async hoverAtCanvasCenter(): Promise<void> { |
| 664 | + const boundingBox = await this.canvasElement.boundingBox(); |
| 665 | + if (!boundingBox) throw new Error('Canvas bounding box not found'); |
| 666 | + const centerX = boundingBox.x + boundingBox.width / 2; |
| 667 | + const centerY = boundingBox.y + boundingBox.height / 2; |
| 668 | + await this.page.mouse.move(centerX, centerY); |
| 669 | + } |
| 670 | + |
| 671 | + async isNodeToolTipVisible(node: string): Promise<boolean> { |
| 672 | + return await this.nodeToolTip(node).isVisible(); |
| 673 | + } |
| 674 | + |
| 675 | + async waitForCanvasAnimationToEnd(timeout = 5000): Promise<void> { |
| 676 | + const canvasHandle = await this.canvasElement.elementHandle(); |
| 677 | + |
| 678 | + if (!canvasHandle) { |
| 679 | + throw new Error("Canvas element not found!"); |
| 680 | + } |
| 681 | + |
| 682 | + await this.page.waitForFunction( |
| 683 | + (canvas) => { |
| 684 | + const ctx = (canvas as HTMLCanvasElement).getContext('2d'); |
| 685 | + if (!ctx) return false; |
| 686 | + |
| 687 | + const imageData1 = ctx.getImageData(0, 0, (canvas as HTMLCanvasElement).width, (canvas as HTMLCanvasElement).height).data; |
| 688 | + |
| 689 | + return new Promise<boolean>((resolve) => { |
| 690 | + setTimeout(() => { |
| 691 | + const imageData2 = ctx.getImageData(0, 0, (canvas as HTMLCanvasElement).width, (canvas as HTMLCanvasElement).height).data; |
| 692 | + resolve(JSON.stringify(imageData1) === JSON.stringify(imageData2)); |
| 693 | + }, 500); |
| 694 | + }); |
| 695 | + }, |
| 696 | + canvasHandle as any, |
| 697 | + { timeout } |
| 698 | + ); |
| 699 | + } |
| 700 | + |
640 | 701 | } |
0 commit comments