From 4d2e171c9b9ae1c7cb2348ec95473dd9674a4636 Mon Sep 17 00:00:00 2001 From: Yusuf Khan <66191792+yuskhan@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:49:31 -0400 Subject: [PATCH] chore: add language options (#35) * chore: add language options * test: add cypress test for language options --------- Co-authored-by: AleksanderBodurri --- cypress.config.ts | 1 + cypress/e2e/ngx-turnstile.cy.ts | 14 +++++++++++++ .../src/app/app.component.ts | 6 ++++++ .../language-option.component.ts | 21 +++++++++++++++++++ projects/ngx-turnstile-demo/src/app/routes.ts | 6 ++++++ projects/ngx-turnstile-demo/src/main.ts | 11 ++++++++++ .../src/lib/interfaces/turnstile-options.ts | 1 + .../src/lib/ngx-turnstile.component.ts | 2 ++ 8 files changed, 62 insertions(+) create mode 100644 projects/ngx-turnstile-demo/src/app/examples/language-option/language-option.component.ts diff --git a/cypress.config.ts b/cypress.config.ts index 9981236..b8a1031 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -12,6 +12,7 @@ export default defineConfig({ baseUrl: 'http://0.0.0.0:4200', reactiveFormUrl: 'http://0.0.0.0:4200/reactive-form-example', templateDrivenFormUrl: 'http://0.0.0.0:4200/template-driven-form-example', + languageOptionUrl: 'http://0.0.0.0:4200/language-option-example', }, e2e: { setupNodeEvents(on, config) { diff --git a/cypress/e2e/ngx-turnstile.cy.ts b/cypress/e2e/ngx-turnstile.cy.ts index 583c8d7..953634e 100644 --- a/cypress/e2e/ngx-turnstile.cy.ts +++ b/cypress/e2e/ngx-turnstile.cy.ts @@ -31,4 +31,18 @@ describe('tests the ngx-turnstile library', () => { '[Cloudflare Turnstile] Turnstile already has been loaded. Was Turnstile imported multiple times?.', ); }); + + it('Passes Language Option Example', () => { + cy.visit(Cypress.env('languageOptionUrl')); + cy.wait(3000); + cy.get('ngx-turnstile').should('have.attr', 'ng-reflect-language', 'FR'); + + // checks the iframe src attribute to make sure the language option was sent to cloudflare correctly + cy.get('ngx-turnstile div') + .shadow() + .find('iframe') + .then(($iframe) => { + cy.wrap($iframe).should('have.attr', 'src').and('include', 'FR'); + }); + }); }); diff --git a/projects/ngx-turnstile-demo/src/app/app.component.ts b/projects/ngx-turnstile-demo/src/app/app.component.ts index 5539c25..77d829f 100644 --- a/projects/ngx-turnstile-demo/src/app/app.component.ts +++ b/projects/ngx-turnstile-demo/src/app/app.component.ts @@ -74,6 +74,12 @@ import { RouterModule } from '@angular/router'; [routerLinkActive]="['route-active']" >Template Driven Form Example + + Language Option Example
diff --git a/projects/ngx-turnstile-demo/src/app/examples/language-option/language-option.component.ts b/projects/ngx-turnstile-demo/src/app/examples/language-option/language-option.component.ts new file mode 100644 index 0000000..00f7ca1 --- /dev/null +++ b/projects/ngx-turnstile-demo/src/app/examples/language-option/language-option.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { NgxTurnstileModule } from 'ngx-turnstile'; + +@Component({ + selector: 'app-regular-example', + standalone: true, + template: ` + + + + `, + imports: [NgxTurnstileModule], +}) +export class LanguageOptionComponent { + siteKey = '1x00000000000000000000AA'; + language = 'FR'; +} diff --git a/projects/ngx-turnstile-demo/src/app/routes.ts b/projects/ngx-turnstile-demo/src/app/routes.ts index cc5a3c3..503d873 100644 --- a/projects/ngx-turnstile-demo/src/app/routes.ts +++ b/projects/ngx-turnstile-demo/src/app/routes.ts @@ -2,6 +2,7 @@ import { Routes } from '@angular/router'; import { EventBindingExampleComponent } from './examples/event-binding/event-binding-example.component'; import { ReactiveFormExampleComponent } from './examples/reactive-form/reactive-form-example.component'; import { TemplateDrivenFormExampleComponent } from './examples/template-driven-form/template-driven-form-example.component'; +import { LanguageOptionComponent } from './examples/language-option/language-option.component'; export const APP_ROUTES: Routes = [ { @@ -15,6 +16,11 @@ export const APP_ROUTES: Routes = [ component: ReactiveFormExampleComponent, title: 'Reactive Form Example', }, + { + path: 'language-option-example', + component: LanguageOptionComponent, + title: 'Language Option Example', + }, { path: 'template-driven-form-example', component: TemplateDrivenFormExampleComponent, diff --git a/projects/ngx-turnstile-demo/src/main.ts b/projects/ngx-turnstile-demo/src/main.ts index 94e9bc9..2371db7 100644 --- a/projects/ngx-turnstile-demo/src/main.ts +++ b/projects/ngx-turnstile-demo/src/main.ts @@ -6,6 +6,17 @@ import { APP_ROUTES } from './app/routes'; import { environment } from './environments/environment'; +function overWriteAttachShadowToPreventClosedShadowDoms() { + const og = HTMLDivElement.prototype.attachShadow; + HTMLDivElement.prototype.attachShadow = function (options: ShadowRootInit) { + if (options.mode === 'closed') { + options.mode = 'open'; + } + return og.call(this, options); + }; +} +overWriteAttachShadowToPreventClosedShadowDoms(); // Open shadow DOMS to enable cypress testing + if (environment.production) { enableProdMode(); } diff --git a/projects/ngx-turnstile/src/lib/interfaces/turnstile-options.ts b/projects/ngx-turnstile/src/lib/interfaces/turnstile-options.ts index fcb454e..f20e296 100644 --- a/projects/ngx-turnstile/src/lib/interfaces/turnstile-options.ts +++ b/projects/ngx-turnstile/src/lib/interfaces/turnstile-options.ts @@ -6,6 +6,7 @@ export interface TurnstileOptions { 'error-callback'?: (errorCode: string) => boolean; 'expired-callback'?: () => void; theme?: 'light' | 'dark' | 'auto'; + language?: string; tabindex?: number; appearance?: 'always' | 'execute' | 'interaction-only'; } diff --git a/projects/ngx-turnstile/src/lib/ngx-turnstile.component.ts b/projects/ngx-turnstile/src/lib/ngx-turnstile.component.ts index 9e5b669..71dc344 100644 --- a/projects/ngx-turnstile/src/lib/ngx-turnstile.component.ts +++ b/projects/ngx-turnstile/src/lib/ngx-turnstile.component.ts @@ -43,6 +43,7 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy { @Input() action?: string; @Input() cData?: string; @Input() theme?: 'light' | 'dark' | 'auto' = 'auto'; + @Input() language?: string = 'auto'; @Input() version: SupportedVersion = '0'; @Input() tabIndex?: number; @Input() appearance?: 'always' | 'execute' | 'interaction-only' = 'always'; @@ -70,6 +71,7 @@ export class NgxTurnstileComponent implements AfterViewInit, OnDestroy { let turnstileOptions: TurnstileOptions = { sitekey: this.siteKey, theme: this.theme, + language: this.language, tabindex: this.tabIndex, action: this.action, cData: this.cData,