diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55ece7b..c7c68ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,10 @@ jobs: node-version-file: '.nvmrc' registry-url: 'https://registry.npmjs.org' cache: 'yarn' + + - name: Install Lerna + run: yarn global add lerna@6 + - run: yarn setup - run: yarn lint --stream - run: yarn build --stream diff --git a/.nvmrc b/.nvmrc index 7da30cb..0cf077e 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.13 +16.14 diff --git a/CHANGES.md b/CHANGES.md index 1a2a98d..6cee72d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changelog +# 1.3.0 + +- Feat: support `custom` prop + # 1.2.1 - Fix: Missing `index.d.ts` for `@hcaptcha/vue3-hcaptcha` diff --git a/README.md b/README.md index f5947cd..fd65c38 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ The component will automatically load the hCaptcha API library and append it to | `challengeContainer` | String | No | `-` | A custom element ID to render the hCaptcha challenge. | | `rqdata` | String | No | - | See Enterprise docs. | | `sentry` | Boolean | No | - | See Enterprise docs. | +| `custom` | Boolean | No | - | See Enterprise docs. | | `apiEndpoint` | String | No | - | See Enterprise docs. | | `endpoint` | String | No | - | See Enterprise docs. | | `reportapi` | String | No | - | See Enterprise docs. | diff --git a/packages/vue2/package.json b/packages/vue2/package.json index 01089c5..78f2561 100644 --- a/packages/vue2/package.json +++ b/packages/vue2/package.json @@ -1,6 +1,6 @@ { "name": "@hcaptcha/vue-hcaptcha", - "version": "1.2.1", + "version": "1.3.0", "types": "types/index.d.ts", "main": "./dist/@hcaptcha/vue-hcaptcha.umd.min.js", "module": "./dist/@hcaptcha/vue-hcaptcha.common.js", diff --git a/packages/vue2/src/__tests__/hcaptcha-script.test.js b/packages/vue2/src/__tests__/hcaptcha-script.test.js index 7e7d6ba..41a3334 100644 --- a/packages/vue2/src/__tests__/hcaptcha-script.test.js +++ b/packages/vue2/src/__tests__/hcaptcha-script.test.js @@ -6,6 +6,7 @@ const config = { language: 'ro', reCaptchaCompat: true, sentry: true, + custom: true, apiEndpoint: 'https://hcaptcha.com/1/api.js', endpoint: 'https://endpoint', reportapi: 'https://reportapi', @@ -52,14 +53,14 @@ describe('hcaptcha-script', () => { test('script src with custom endpoint', () => { expect(getScriptSrc(config)) - .toBe('https://hcaptcha.com/1/api.js?render=explicit&onload=_hcaptchaOnLoad&hl=ro&sentry=true&endpoint=https%3A%2F%2Fendpoint&assethost=https%3A%2F%2Fassethost&imghost=https%3A%2F%2Fimghost&reportapi=https%3A%2F%2Freportapi'); + .toBe('https://hcaptcha.com/1/api.js?render=explicit&onload=_hcaptchaOnLoad&hl=ro&sentry=true&custom=true&endpoint=https%3A%2F%2Fendpoint&assethost=https%3A%2F%2Fassethost&imghost=https%3A%2F%2Fimghost&reportapi=https%3A%2F%2Freportapi'); }); test('script src with reCaptchaCompat off', () => { const cfg = Object.assign({}, config); cfg.reCaptchaCompat = false; expect(getScriptSrc(cfg)) - .toBe('https://hcaptcha.com/1/api.js?render=explicit&onload=_hcaptchaOnLoad&recaptchacompat=off&hl=ro&sentry=true&endpoint=https%3A%2F%2Fendpoint&assethost=https%3A%2F%2Fassethost&imghost=https%3A%2F%2Fimghost&reportapi=https%3A%2F%2Freportapi'); + .toBe('https://hcaptcha.com/1/api.js?render=explicit&onload=_hcaptchaOnLoad&recaptchacompat=off&hl=ro&sentry=true&custom=true&endpoint=https%3A%2F%2Fendpoint&assethost=https%3A%2F%2Fassethost&imghost=https%3A%2F%2Fimghost&reportapi=https%3A%2F%2Freportapi'); }); diff --git a/packages/vue2/src/hcaptcha-script.js b/packages/vue2/src/hcaptcha-script.js index d6b2c15..55d2bbd 100644 --- a/packages/vue2/src/hcaptcha-script.js +++ b/packages/vue2/src/hcaptcha-script.js @@ -62,6 +62,7 @@ export function getScriptSrc(config) { scriptSrc = addQueryParamIfDefined(scriptSrc, 'recaptchacompat', config.reCaptchaCompat === false ? 'off' : null); scriptSrc = addQueryParamIfDefined(scriptSrc, 'hl', config.language); scriptSrc = addQueryParamIfDefined(scriptSrc, 'sentry', config.sentry); + scriptSrc = addQueryParamIfDefined(scriptSrc, 'custom', config.custom); scriptSrc = addQueryParamIfDefined(scriptSrc, 'endpoint', config.endpoint); scriptSrc = addQueryParamIfDefined(scriptSrc, 'assethost', config.assethost); scriptSrc = addQueryParamIfDefined(scriptSrc, 'imghost', config.imghost); diff --git a/packages/vue2/src/hcaptcha.vue b/packages/vue2/src/hcaptcha.vue index 0e2430d..d45a636 100644 --- a/packages/vue2/src/hcaptcha.vue +++ b/packages/vue2/src/hcaptcha.vue @@ -44,6 +44,10 @@ export default { type: Boolean, default: true }, + custom: { + type: Boolean, + default: undefined + }, apiEndpoint: { type: String, default: 'https://hcaptcha.com/1/api.js' diff --git a/packages/vue2/types/index.d.ts b/packages/vue2/types/index.d.ts index 87a0a9d..45852d5 100644 --- a/packages/vue2/types/index.d.ts +++ b/packages/vue2/types/index.d.ts @@ -10,6 +10,7 @@ declare class VueHcaptcha extends Vue { challengeContainer?: string; rqdata?: string; sentry?: boolean; + custom?: boolean; endpoint?: string; reportapi?: string; assethost?: string; diff --git a/packages/vue3/package.json b/packages/vue3/package.json index e3a0235..4bfb6e4 100644 --- a/packages/vue3/package.json +++ b/packages/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@hcaptcha/vue3-hcaptcha", - "version": "1.2.1", + "version": "1.3.0", "author": "hCaptcha team and contributors", "homepage": "https://github.com/hCaptcha/vue-hcaptcha", "organization": "hCaptcha", diff --git a/packages/vue3/test/e2e/hcaptcha.test.js b/packages/vue3/test/e2e/hcaptcha.test.js index 19fb4d1..e8cd58c 100644 --- a/packages/vue3/test/e2e/hcaptcha.test.js +++ b/packages/vue3/test/e2e/hcaptcha.test.js @@ -49,7 +49,8 @@ async function waitForFrame(ownerFrame, name, hcaptchaId) { { state: "attached" } ); const frame = await elem.contentFrame(); - await frame.waitForLoadState(); + await frame.waitForLoadState("networkidle"); + return { elem, frame }; } @@ -72,10 +73,14 @@ describe("hCaptcha vue3", () => { beforeEach(async () => { page = await browser.newPage({ bypassCSP: true }); + setupPage(page); + await page.setViewportSize({ width: 1280, height: 720 }); await page.route(/https:\/\/hcaptcha\.local/, route => route.fulfill({ body: HTML })); await page.goto("https://hcaptcha.local"); + + await page.waitForLoadState("networkidle"); }); afterEach(async () => { @@ -85,18 +90,22 @@ describe("hCaptcha vue3", () => { it("should render anchor", async () => { const { frame } = await waitForFrame(page, "checkbox"); const anchor = await frame.$("#anchor"); + expect(await anchor.screenshot()).toMatchImageSnapshot({ failureThreshold: 0.01 }); }); it("should get token", async () => { const onVerifyMock = jest.fn(); await page.exposeBinding("onVerify", onVerifyMock); - const getRequestPromise = page.waitForRequest("**/getcaptcha?*"); + const { frame } = await waitForFrame(page, "checkbox"); const anchor = await frame.$("#anchor"); + await anchor.click(); - await getRequestPromise; + await page.waitForRequest("**/getcaptcha?*"); + await frame.waitForSelector(".check"); + expect(onVerifyMock).toHaveBeenCalledTimes(1); expect(onVerifyMock).toHaveBeenCalledWith(expect.anything(), { token: "10000000-aaaa-bbbb-cccc-000000000001", eKey: "" }); expect(await anchor.screenshot()).toMatchImageSnapshot({ failureThreshold: 0.01 });