From dd2738722b61d98c616737f299e3bd4108b4dc37 Mon Sep 17 00:00:00 2001 From: Ivan Lagunovsky Date: Mon, 27 Feb 2023 08:29:32 +0100 Subject: [PATCH] fix(plugin-recaptcha): Solve hcaptcha on newassets.hcaptcha.com (#771) --- .../src/content-hcaptcha.ts | 9 ++- .../src/index.test.ts | 66 +++++++++++-------- .../src/solve.test.ts | 30 +++++---- 3 files changed, 63 insertions(+), 42 deletions(-) diff --git a/packages/puppeteer-extra-plugin-recaptcha/src/content-hcaptcha.ts b/packages/puppeteer-extra-plugin-recaptcha/src/content-hcaptcha.ts index 191bc66ff..935c238b2 100644 --- a/packages/puppeteer-extra-plugin-recaptcha/src/content-hcaptcha.ts +++ b/packages/puppeteer-extra-plugin-recaptcha/src/content-hcaptcha.ts @@ -16,7 +16,10 @@ export class HcaptchaContentScript { private opts: types.ContentScriptOpts private data: types.ContentScriptData - private baseUrl = 'assets.hcaptcha.com/captcha/v1/' + private baseUrls = [ + 'assets.hcaptcha.com/captcha/v1/', + 'newassets.hcaptcha.com/captcha/v1/', + ] constructor( opts = ContentScriptDefaultOpts, @@ -57,7 +60,7 @@ export class HcaptchaContentScript { /** Regular checkboxes */ private _findRegularCheckboxes() { const nodeList = document.querySelectorAll( - `iframe[src*='${this.baseUrl}'][data-hcaptcha-widget-id]:not([src*='invisible'])` + this.baseUrls.map(url => `iframe[src*='${url}'][data-hcaptcha-widget-id]:not([src*='invisible'])`).join(',') ) return Array.from(nodeList) } @@ -65,7 +68,7 @@ export class HcaptchaContentScript { /** Find active challenges from invisible hcaptchas */ private _findActiveChallenges() { const nodeList = document.querySelectorAll( - `div[style*='visible'] iframe[src*='${this.baseUrl}'][src*='hcaptcha.html']` + this.baseUrls.map(url => `div[style*='visible'] iframe[src*='${url}'][src*='hcaptcha.html']`).join(',') ) return Array.from(nodeList) } diff --git a/packages/puppeteer-extra-plugin-recaptcha/src/index.test.ts b/packages/puppeteer-extra-plugin-recaptcha/src/index.test.ts index 1581d110b..975a2279d 100644 --- a/packages/puppeteer-extra-plugin-recaptcha/src/index.test.ts +++ b/packages/puppeteer-extra-plugin-recaptcha/src/index.test.ts @@ -48,17 +48,23 @@ test('will detect hCAPTCHAs', async t => { }) const page = await browser.newPage() - const url = 'https://democaptcha.com/demo-form-eng/hcaptcha.html' - await page.goto(url, { waitUntil: 'networkidle0' }) + const urls = [ + 'https://accounts.hcaptcha.com/demo', + 'http://democaptcha.com/demo-form-eng/hcaptcha.html', + ] - const { captchas, error } = await (page as any).findRecaptchas() - t.is(error, null) - t.is(captchas.length, 1) + for (const url of urls) { + await page.goto(url, { waitUntil: 'networkidle0' }) - const c = captchas[0] - t.is(c._vendor, 'hcaptcha') - t.is(c.url, url) - t.true(c.sitekey && c.sitekey.length > 5) + const { captchas, error } = await (page as any).findRecaptchas() + t.is(error, null) + t.is(captchas.length, 1) + + const c = captchas[0] + t.is(c._vendor, 'hcaptcha') + t.is(c.url, url) + t.true(c.sitekey && c.sitekey.length > 5) + } await browser.close() }) @@ -74,24 +80,30 @@ test('will detect active hCAPTCHA challenges', async t => { }) const page = await browser.newPage() - const url = 'https://democaptcha.com/demo-form-eng/hcaptcha.html' - await page.goto(url, { waitUntil: 'networkidle0' }) - await page.evaluate(() => (window as any).hcaptcha.execute()) // trigger challenge popup - await page.waitForTimeout(2 * 1000) - await page.evaluate(() => - document - .querySelector(`[data-hcaptcha-widget-id]:not([src*='invisible'])`) - .remove() - ) // remove regular checkbox so we definitely test against the popup - - const { captchas, error } = await (page as any).findRecaptchas() - t.is(error, null) - t.is(captchas.length, 1) - - const c = captchas[0] - t.is(c._vendor, 'hcaptcha') - t.is(c.url, url) - t.true(c.sitekey && c.sitekey.length > 5) + const urls = [ + 'https://accounts.hcaptcha.com/demo', + 'http://democaptcha.com/demo-form-eng/hcaptcha.html', + ] + + for (const url of urls) { + await page.goto(url, { waitUntil: 'networkidle0' }) + await page.evaluate(() => (window as any).hcaptcha.execute()) // trigger challenge popup + await page.waitForTimeout(2 * 1000) + await page.evaluate(() => + document + .querySelector(`[data-hcaptcha-widget-id]:not([src*='invisible'])`) + .remove() + ) // remove regular checkbox so we definitely test against the popup + + const { captchas, error } = await (page as any).findRecaptchas() + t.is(error, null) + t.is(captchas.length, 1) + + const c = captchas[0] + t.is(c._vendor, 'hcaptcha') + t.is(c.url, url) + t.true(c.sitekey && c.sitekey.length > 5) + } await browser.close() }) diff --git a/packages/puppeteer-extra-plugin-recaptcha/src/solve.test.ts b/packages/puppeteer-extra-plugin-recaptcha/src/solve.test.ts index 5a6b829a7..153c15ca5 100644 --- a/packages/puppeteer-extra-plugin-recaptcha/src/solve.test.ts +++ b/packages/puppeteer-extra-plugin-recaptcha/src/solve.test.ts @@ -67,18 +67,24 @@ test('will solve hCAPTCHAs', async t => { }) const page = await browser.newPage() - const url = 'http://democaptcha.com/demo-form-eng/hcaptcha.html' - await page.goto(url, { waitUntil: 'networkidle0' }) - - const result = await (page as any).solveRecaptchas() - const { captchas, solutions, solved, error } = result - t.falsy(error) - - t.is(captchas.length, 1) - t.is(solutions.length, 1) - t.is(solved.length, 1) - t.is(solved[0]._vendor, 'hcaptcha') - t.is(solved[0].isSolved, true) + const urls = [ + 'https://accounts.hcaptcha.com/demo', + 'http://democaptcha.com/demo-form-eng/hcaptcha.html', + ] + + for (const url of urls) { + await page.goto(url, { waitUntil: 'networkidle0' }) + + const result = await (page as any).solveRecaptchas() + const { captchas, solutions, solved, error } = result + t.falsy(error) + + t.is(captchas.length, 1) + t.is(solutions.length, 1) + t.is(solved.length, 1) + t.is(solved[0]._vendor, 'hcaptcha') + t.is(solved[0].isSolved, true) + } await browser.close() })