Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions assets/js/hcaptcha-gravity-forms.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
/* global jQuery */

( function( $ ) {
// Replay the click so Gravity Forms and custom onclick handlers run.
wp.hooks.addFilter(
'hcaptcha.ajaxSubmitButton',
'hcaptcha',
( isAjaxSubmitButton, submitButtonElement ) => {
return submitButtonElement.id.startsWith( 'gform_submit_button_' ) || isAjaxSubmitButton;
},
);

$( document ).on( 'gform_post_render', function( e, formId ) {
const $form = $( '#gform_' + formId );

Expand Down
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fixed delayed hCaptcha loading after interaction with Beaver Builder login forms.
* Fixed GiveWP compatibility.
* Fixed Paid Membership Pro compatibility.
* Fixed Gravity Forms block submissions to prevent the “Unsupported submission flow” warning.

= 5.2.0 =
* Added MetForm integration.
Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ Instructions for popular native integrations are below:
* Fixed delayed hCaptcha loading after interaction with Beaver Builder login forms.
* Fixed GiveWP compatibility.
* Fixed Paid Membership Pro compatibility.
* Fixed Gravity Forms block submissions to prevent the “Unsupported submission flow” warning.

= 5.2.0 =
* Added MetForm integration.
Expand Down
2 changes: 1 addition & 1 deletion src/php/GravityForms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public function enqueue_scripts(): void {
wp_enqueue_script(
self::HANDLE,
HCAPTCHA_URL . "/assets/js/hcaptcha-gravity-forms$min.js",
[ 'jquery' ],
[ 'jquery', 'wp-hooks' ],
HCAPTCHA_VERSION,
true
);
Expand Down
79 changes: 79 additions & 0 deletions tests/js/assets-js-files/hcaptcha-gravity-forms.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
// noinspection JSUnresolvedFunction,JSUnresolvedVariable

import $ from 'jquery';
import { createHooks } from '@wordpress/hooks';
import HCaptcha from '../../../src/js/hcaptcha/hcaptcha.js';

global.jQuery = $;
global.$ = $;

beforeEach( () => {
global.wp = { hooks: createHooks() };
} );

afterEach( () => {
delete global.wp;
delete global.hcaptcha;
delete window.gform;
document.body.innerHTML = '';
} );

describe( 'hCaptcha Gravity Forms frontend', () => {
beforeEach( () => {
jest.resetModules();
Expand All @@ -31,6 +44,72 @@ describe( 'hCaptcha Gravity Forms frontend', () => {
$( document ).trigger( 'gform_post_render', [ 2 ] );
expect( window.hCaptchaBindEvents ).toHaveBeenCalledTimes( 1 );
} );

test.each( [
[ 'input', 'invisible', '' ],
[ 'button', 'invisible', 'gform_ajax_frame_40' ],
[ 'input', 'normal', 'gform_ajax_frame_40' ],
[ 'button', 'normal', '' ],
] )( 'runs Gravity Forms and custom onclick handlers after %s verification (%s, target=%s)', ( tag, size, target ) => {
document.body.innerHTML = `
<div class="gform_wrapper">
<form id="gform_40" target="${ target }">
<div class="h-captcha" data-size="${ size }" data-force="${ size === 'normal' }"></div>
</form>
</div>
`;
const form = document.getElementById( 'gform_40' );
const button = document.createElement( tag );
button.type = 'submit';
button.id = 'gform_submit_button_40';
button.setAttribute( 'onclick', `
window.gform.submission.handleButtonClick(this);
var formEl = this.closest('.gform_wrapper');
let div = document.createElement('div');
div.classList.add('gform_yelp_spinner');
formEl.append(div);
formEl.classList.add('submitting');
` );
form.appendChild( button );
form.addEventListener( 'submit', ( event ) => event.preventDefault() );
const requestSubmit = jest.spyOn( form, 'requestSubmit' );
const handleButtonClick = jest.fn();
window.gform = { submission: { handleButtonClick } };
global.hcaptcha = { execute: jest.fn() };
const hCaptcha = new HCaptcha();
hCaptcha.setParams( { size } );
jest.spyOn( hCaptcha, 'render' ).mockImplementation( ( element ) => {
element.innerHTML = '<textarea name="h-captcha-response"></textarea>';
return 'widget-40';
} );
hCaptcha.bindEvents();

button.click();

expect( global.hcaptcha.execute ).toHaveBeenCalledTimes( 1 );
expect( handleButtonClick ).not.toHaveBeenCalled();
expect( document.querySelector( '.gform_yelp_spinner' ) ).toBeNull();

form.querySelector( '[name="h-captcha-response"]' ).value = 'verified-token';
hCaptcha.callback( 'verified-token' );

expect( handleButtonClick ).toHaveBeenCalledTimes( 1 );
expect( handleButtonClick ).toHaveBeenCalledWith( button );
expect( document.querySelectorAll( '.gform_yelp_spinner' ) ).toHaveLength( 1 );
expect( form.parentElement.classList.contains( 'submitting' ) ).toBe( true );
expect( global.hcaptcha.execute ).toHaveBeenCalledTimes( 1 );
expect( requestSubmit ).not.toHaveBeenCalled();
expect( button.disabled ).toBe( false );
} );

test.each( [ false, true ] )( 'preserves other forms ajax submit status (%s)', ( isAjaxSubmitButton ) => {
const button = document.createElement( 'button' );
button.type = 'submit';
button.id = 'other_submit_button_40';

expect( wp.hooks.applyFilters( 'hcaptcha.ajaxSubmitButton', isAjaxSubmitButton, button ) )
.toBe( isAjaxSubmitButton );
} );
} );

describe( 'hCaptcha Gravity Forms null form branch', () => {
Expand Down
1 change: 1 addition & 0 deletions tests/php/integration/GravityForms/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ public function test_enqueue_scripts(): void {
$subject->enqueue_scripts();

self::assertTrue( wp_script_is( Form::HANDLE ) );
self::assertContains( 'wp-hooks', wp_scripts()->registered[ Form::HANDLE ]->deps );
}

/**
Expand Down