yaGeey commited on
Commit
7102b00
·
1 Parent(s): 72a2326
Files changed (2) hide show
  1. src/actions.ts +36 -37
  2. src/browser.ts +2 -0
src/actions.ts CHANGED
@@ -17,38 +17,38 @@ const dismissConsentIfPresent = async (page: Page) => {
17
  }
18
 
19
  export const addToPlaylistAction = async (page: Page) => {
20
- const slowHostTimeoutMs = 90000
21
 
22
- await page.waitForLoadState('domcontentloaded', { timeout: slowHostTimeoutMs })
23
- console.log('page loaded')
24
  await dismissConsentIfPresent(page)
25
- console.log('page loaded and dissmissed')
26
 
27
  const track = page.locator('[data-testid="tracklist-row"]').first()
28
  await track.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
29
- console.log('track visible')
30
 
 
 
31
  await track.click({ button: 'right', timeout: slowHostTimeoutMs })
32
- console.log('track right-clicked')
33
 
34
  const menu = page.locator('[data-testid="context-menu"]')
35
- await menu.waitFor({ timeout: slowHostTimeoutMs })
36
- console.log('context menu visible')
37
 
38
  const addToPlaylistButton = menu.getByText('Add to Playlist', { exact: false })
39
- await addToPlaylistButton.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
40
- console.log('add to playlist button visible')
41
- await addToPlaylistButton.hover({ timeout: slowHostTimeoutMs })
42
- console.log('add to playlist button hovered')
43
 
44
  const input = page.locator('[placeholder="Find a playlist"]')
45
  await input.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
46
- console.log('playlist search input visible')
47
- await input.fill('TEST', { timeout: slowHostTimeoutMs })
48
- console.log('playlist search input filled')
49
- // await page.waitForTimeout(5000)
50
- console.log('waited for search results to populate')
51
 
 
 
 
 
 
 
 
 
 
 
52
  const targetPlaylist = page.getByRole('menuitem', { name: 'TEST', exact: true }).first()
53
  if (!(await targetPlaylist.isVisible())) {
54
  console.log('playlist not found in search results, clicking search result to trigger playlist loading')
@@ -64,26 +64,25 @@ export const addToPlaylistAction = async (page: Page) => {
64
  console.log('clicked playlist in search results')
65
  }
66
 
67
- // Wait for context menu to close
68
- await menu.waitFor({ state: 'hidden', timeout: 5000 }).catch(() => console.log('menu did not hide'))
69
- console.log('context menu closed')
70
-
71
- // Wait for UI to settle
72
- await page.waitForTimeout(2000)
73
-
74
- // Check if "Already added" dialog appeared (only if song was already in playlist)
75
- const addAnywayBtn = page.getByRole('button', { name: /add anyway/i })
76
- await addAnywayBtn.waitFor({ timeout: 5000 }).catch(() => console.log('"Add anyway" button did not appear'))
77
- const isVisible = await addAnywayBtn.isVisible().catch(() => false)
78
- console.log(`is "Add anyway" button visible? ${isVisible}`)
79
- if (isVisible) {
80
- await addAnywayBtn.click({ timeout: slowHostTimeoutMs })
81
- console.log('clicked "Add anyway" button')
82
- }
83
 
84
- // Wait for addToPlaylist operation to fire
85
- console.log('waiting for addToPlaylist operation to fire...')
86
- await page.waitForTimeout(10000)
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
- console.log('finished addToPlaylistAction')
 
89
  }
 
17
  }
18
 
19
  export const addToPlaylistAction = async (page: Page) => {
20
+ const slowHostTimeoutMs = 90000 // Зменшив, 90с це занадто, краще впасти раніше
21
 
22
+ await page.waitForLoadState('networkidle', { timeout: slowHostTimeoutMs }) // Важливо: networkidle краще ніж domcontentloaded для SPA
 
23
  await dismissConsentIfPresent(page)
 
24
 
25
  const track = page.locator('[data-testid="tracklist-row"]').first()
26
  await track.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
 
27
 
28
+ // ТРЮК 1: Примусовий скрол до елемента перед кліком
29
+ await track.scrollIntoViewIfNeeded()
30
  await track.click({ button: 'right', timeout: slowHostTimeoutMs })
 
31
 
32
  const menu = page.locator('[data-testid="context-menu"]')
33
+ await menu.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
 
34
 
35
  const addToPlaylistButton = menu.getByText('Add to Playlist', { exact: false })
36
+ await addToPlaylistButton.waitFor({ state: 'visible' })
37
+ await addToPlaylistButton.hover() // Hover обов'язковий
 
 
38
 
39
  const input = page.locator('[placeholder="Find a playlist"]')
40
  await input.waitFor({ state: 'visible', timeout: slowHostTimeoutMs })
 
 
 
 
 
41
 
42
+ // ТРЮК 2: Повільний ввід тексту. Це дає React час обробити стейт.
43
+ // Замість fill використовуємо pressSequentially з затримкою
44
+ await input.pressSequentially('TEST', { delay: 100 })
45
+
46
+ // Даємо час на рендеринг відфільтрованого списку
47
+ await page.waitForTimeout(1500)
48
+
49
+ // ТРЮК 3: Замість кліку мишкою - ENTER
50
+ // Після пошуку фокус зазвичай залишається в input або перший елемент стає активним.
51
+ // Спробуємо натиснути стрілку вниз (щоб точно вибрати плейліст) і Enter.
52
  const targetPlaylist = page.getByRole('menuitem', { name: 'TEST', exact: true }).first()
53
  if (!(await targetPlaylist.isVisible())) {
54
  console.log('playlist not found in search results, clicking search result to trigger playlist loading')
 
64
  console.log('clicked playlist in search results')
65
  }
66
 
67
+ // Wait for context menu to close implicitly
68
+ await menu.waitFor({ state: 'hidden', timeout: 15000 }).catch(() => {})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ // --- БЛОК ОБРОБКИ "Add Anyway" ---
71
+ // Тут важливо чекати не просто появи, а появи АБО зникнення діалогу
72
+ // Але оскільки нам треба клікнути, чекаємо кнопку.
73
+
74
+ try {
75
+ const addAnywayBtn = page.getByRole('button', { name: /add anyway/i })
76
+ // Чекаємо трохи довше, бо модалка може мати анімацію появи
77
+ await addAnywayBtn.waitFor({ state: 'visible', timeout: 15000 })
78
+
79
+ console.log('"Add anyway" visible, clicking...')
80
+ // Тут теж краще без force, якщо можливо, але для мо��алок force допустимий
81
+ await addAnywayBtn.click()
82
+ } catch (e) {
83
+ console.log('"Add anyway" button did not appear (track likely added or not duplicate)')
84
+ }
85
 
86
+ // Фінальне очікування, щоб запит встиг піти
87
+ await page.waitForTimeout(3000)
88
  }
src/browser.ts CHANGED
@@ -22,6 +22,8 @@ export async function createInstance() {
22
  locale: 'en-US',
23
  timezoneId: 'America/New_York',
24
  bypassCSP: true,
 
 
25
  })
26
  await context.addCookies([
27
  {
 
22
  locale: 'en-US',
23
  timezoneId: 'America/New_York',
24
  bypassCSP: true,
25
+ // viewport: { width: 1920, height: 1080 }, // <--- ДОДАЙ ЦЕ
26
+ deviceScaleFactor: 1,
27
  })
28
  await context.addCookies([
29
  {