diff --git a/app/javascript/packages/document-capture/components/acuant-capture.tsx b/app/javascript/packages/document-capture/components/acuant-capture.tsx
index 6bc85b80884..6a7bf111812 100644
--- a/app/javascript/packages/document-capture/components/acuant-capture.tsx
+++ b/app/javascript/packages/document-capture/components/acuant-capture.tsx
@@ -529,7 +529,6 @@ function AcuantCapture(
});
setImageCaptureText('');
- setIsCapturingEnvironment(true);
}
function onSelfieCaptureClosed() {
diff --git a/app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx b/app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx
index 86dab1889a2..916f75a9ffd 100644
--- a/app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx
+++ b/app/javascript/packages/document-capture/components/acuant-selfie-capture-canvas.jsx
@@ -21,6 +21,16 @@ function AcuantSelfieCaptureCanvas({ imageCaptureText, onSelfieCaptureClosed })
// The Acuant SDK script AcuantPassiveLiveness attaches to whatever element has
// this id. It then uses that element as the root for the full screen selfie capture
const acuantCaptureContainerId = 'acuant-face-capture-container';
+
+ // This solves a fairly nasty bug for screenreader users where the screenreader focus would jump away
+ // from the capture button (added by Acuant SDK) to the button in this component. Specifically we
+ // need to detect when Acuant actually hydrates in their capture screen and hide the button.
+ // See PR 10668 for more information.
+ const elementInShadow = document
+ ?.getElementById('acuant-face-capture-camera')
+ ?.shadowRoot?.getElementById('cameraContainer');
+ const loadedAcuantCamera = !!elementInShadow;
+
return (
<>
{!isReady && }
@@ -31,9 +41,11 @@ function AcuantSelfieCaptureCanvas({ imageCaptureText, onSelfieCaptureClosed })
)}
-
+ {!loadedAcuantCamera && (
+
+ )}
>
);
}
diff --git a/spec/javascript/packages/document-capture/components/acuant-selfie-capture-canvas-spec.jsx b/spec/javascript/packages/document-capture/components/acuant-selfie-capture-canvas-spec.jsx
index e862a1fcd79..0a54a25f1af 100644
--- a/spec/javascript/packages/document-capture/components/acuant-selfie-capture-canvas-spec.jsx
+++ b/spec/javascript/packages/document-capture/components/acuant-selfie-capture-canvas-spec.jsx
@@ -27,3 +27,47 @@ it('shows the Acuant div when the script has loaded', () => {
expect(container.querySelector('#acuant-face-capture-container')).to.exist();
expect(container.querySelector('.acuant-capture-canvas__spinner')).not.to.exist();
});
+
+it('shows the fullscreen close button before acuant is hydrated in', () => {
+ // Render the AcuantSelfieCaptureCanvas component with some text
+ const imageCaptureText = 'Face not found';
+ const { rerender, container, queryByRole } = render(
+
+
+
+
+ ,
+ );
+ // Check that the button exists
+ expect(queryByRole('button')).to.exist();
+
+ // Mock how Acuant sets up the dom by creating this structure of divs
+ // '#acuant-face-capture-container>#acuant-face-capture-camera>#cameraContainer'
+ const acuantFaceCaptureDiv = document.createElement('div');
+ acuantFaceCaptureDiv.id = 'acuant-face-capture-camera';
+ const acuantFaceCaptureContainer = container.querySelector('#acuant-face-capture-container');
+ acuantFaceCaptureContainer.appendChild(acuantFaceCaptureDiv);
+ expect(
+ container.querySelector('#acuant-face-capture-container>#acuant-face-capture-camera'),
+ ).to.exist();
+
+ // Mock how Acuant sets up the shadow dom with the #cameraContainer div inside it
+ const cameraContainer = document.createElement('div');
+ cameraContainer.id = 'cameraContainer';
+ const shadow = container
+ .querySelector('#acuant-face-capture-camera')
+ .attachShadow({ mode: 'open' });
+ shadow.appendChild(cameraContainer);
+
+ // Rerender the component, the shadow dom continues to exist
+ const newImageCaptureText = 'Too many faces';
+ rerender(
+
+
+
+
+ ,
+ );
+ // The button now disappears
+ expect(queryByRole('button')).not.to.exist();
+});