File size: 1,431 Bytes
05c5ed5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { Page } from "@playwright/test";

/**
 * Generate a unique test name with timestamp and random string
 */
export function uniqueTestName(prefix: string): string {
  return `${prefix} ${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

/**
 * Click an element and wait for navigation to complete
 * Prevents race conditions between click and navigation
 */
export async function clickAndWaitForNavigation(
  page: Page,
  selector: string,
  urlPattern: string,
  options = { timeout: 10000 },
) {
  await Promise.all([
    page.waitForURL(urlPattern, options),
    page.getByTestId(selector).click(),
  ]);
}

/**
 * Click a dropdown button and wait for menu to appear
 * Handles flaky shadcn dropdown behaviors
 */
export async function openDropdown(
  page: Page,
  buttonSelector: string,
  menuSelector = '[role="menu"]',
  timeout = 5000,
) {
  const button = page.getByTestId(buttonSelector);
  await button.click();

  const menu = page.locator(menuSelector);
  await menu.waitFor({ state: "visible", timeout });
  return menu;
}

/**
 * Select an option from an open dropdown menu
 */
export async function selectDropdownOption(
  page: Page,
  optionSelector: string,
  timeout = 5000,
) {
  const option = page.getByTestId(optionSelector);
  await option.waitFor({ state: "visible", timeout });
  await option.click();

  // Wait for menu to close
  await option.waitFor({ state: "hidden", timeout });
}