diff --git a/CHANGELOG.md b/CHANGELOG.md index 181e8d6c..b147a4c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added new designs to smart selfie authentication + +## [1.3.8] - 2024-08-15 + +### Changed + +- Updated the button in id types selection screen to use the theme color provided + ## [1.3.7] - 2024-08-14 ### Changed diff --git a/example/package-lock.json b/example/package-lock.json index 3b9b5a29..d4554979 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -1,12 +1,12 @@ { "name": "example", - "version": "1.3.7", + "version": "1.3.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "example", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "@smileid/web-components": "file:../packages/web-components", "cors": "^2.8.5", @@ -21,7 +21,7 @@ }, "../packages/web-components": { "name": "@smileid/web-components", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "signature_pad": "^5.0.2", "validate.js": "^0.13.1" diff --git a/example/package.json b/example/package.json index f002aa20..80815ba4 100644 --- a/example/package.json +++ b/example/package.json @@ -1,7 +1,7 @@ { "name": "example", "private": true, - "version": "1.3.7", + "version": "1.3.8", "type": "module", "main": "server.js", "scripts": { diff --git a/example/script.js b/example/script.js index ac471e85..ea3b5f6a 100644 --- a/example/script.js +++ b/example/script.js @@ -72,10 +72,11 @@ export default function setupForm() { product, callback_url, environment, - // demo_mode: true, use_new_component: true, + //demo_mode: true, // previewBVNMFA: true, document_capture_modes: ['camera', 'upload'], + allow_agent_mode: true, partner_details: { partner_id, signature, @@ -83,7 +84,7 @@ export default function setupForm() { name: 'Demo Account', logo_url: 'https://via.placeholder.com/50/000000/FFFFFF?text=DA', policy_url: 'https://smileidentity.com/privacy-privacy', - theme_color: '#000', + theme_color: '#96002d', }, onSuccess: () => { resetButton(); diff --git a/package-lock.json b/package-lock.json index 71529e36..b24a03ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@smileid/web", - "version": "1.3.7", + "version": "1.3.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@smileid/web", - "version": "1.3.7", + "version": "1.3.8", "license": "MIT", "workspaces": [ "packages/web-components/*/*", @@ -14660,7 +14660,7 @@ }, "packages/embed": { "name": "@smileid/embed", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "@sentry/browser": "^8.13.0", "@sentry/esbuild-plugin": "^2.20.1", @@ -14687,7 +14687,7 @@ }, "packages/smart-camera-web": { "name": "@smile_identity/smart-camera-web", - "version": "1.3.7", + "version": "1.3.8", "license": "MIT", "devDependencies": { "@cypress/code-coverage": "^3.12.39", @@ -14701,7 +14701,7 @@ }, "packages/web-components": { "name": "@smileid/web-components", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "signature_pad": "^5.0.2", "validate.js": "^0.13.1" @@ -14721,7 +14721,7 @@ }, "packages/web-components/components/signature-pad": { "name": "@smileid/signature-pad", - "version": "1.3.7", + "version": "1.3.8", "dependencies": { "signature_pad": "^5.0.2" }, diff --git a/package.json b/package.json index 3d644fce..0854f9c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@smileid/web", - "version": "1.3.7", + "version": "1.3.8", "description": "A collection of SmileID browser clients and components", "main": "index.js", "private": true, diff --git a/packages/embed/cypress/pages/smartselfie-new-design.html b/packages/embed/cypress/pages/smartselfie-new-design.html new file mode 100644 index 00000000..ea6694d8 --- /dev/null +++ b/packages/embed/cypress/pages/smartselfie-new-design.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + diff --git a/packages/embed/cypress/support/commands.js b/packages/embed/cypress/support/commands.js index 01da535b..9dee03cd 100644 --- a/packages/embed/cypress/support/commands.js +++ b/packages/embed/cypress/support/commands.js @@ -257,3 +257,55 @@ Cypress.Commands.add('navigateThroughCameraScreens', () => { .find('#select-selfie') .click(); }); + +Cypress.Commands.add('navigateThroughNewCameraScreens', () => { + cy.log('SmartCameraWeb: disable image tests'); + + cy.getIFrameBody() + .find('smart-camera-web') + .invoke('attr', 'disable-image-tests', 'true'); + + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture-instructions') + .shadow() + .find('#allow') + .click(); + + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture-instructions') + .should('not.be.visible'); + + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture') + .should('be.visible'); + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('contain.text', 'Take a Selfie'); + + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .find('#start-image-capture') + .click(); + + cy.wait(8000); + + cy.getIFrameBody() + .find('smart-camera-web') + .shadow() + .find('selfie-capture-review') + .shadow() + .find('#select-id-image') + .click(); +}); diff --git a/packages/embed/cypress/tests/smartselfie-auth-new-design.cy.cjs b/packages/embed/cypress/tests/smartselfie-auth-new-design.cy.cjs new file mode 100644 index 00000000..a1ccc104 --- /dev/null +++ b/packages/embed/cypress/tests/smartselfie-auth-new-design.cy.cjs @@ -0,0 +1,77 @@ +describe('smartselfie authentication', () => { + beforeEach(() => { + cy.visit('/smartselfie-new-design'); + + cy.getIFrameBody().should('be.visible'); + + cy.intercept( + { + method: 'POST', + url: '*upload*', + }, + { + upload_url: + 'https://smile-uploads-development01.s3.us-west-2.amazonaws.com/videos/212/212-0000060103-0gdzke3mdtlco5k0sdfh6vifzcrd3n/smartselfie.zip', + }, + ).as('getUploadURL'); + }); + + describe('when a successful upload happens', () => { + beforeEach(() => { + cy.intercept( + { + method: 'PUT', + url: 'https://smile-uploads-development01.s3.us-west-2.amazonaws.com/videos/212/212-0000060103-0gdzke3mdtlco5k0sdfh6vifzcrd3n/smartselfie.zip', + }, + { + statusCode: 200, + }, + ).as('successfulUpload'); + cy.navigateThroughNewCameraScreens(); + }); + + it('should show the completion screen', () => { + cy.wait('@getUploadURL'); + + cy.wait('@successfulUpload'); + cy.getIFrameBody().find('#complete-screen').should('be.visible'); + }); + }); + + describe('when the upload fails', () => { + beforeEach(() => { + cy.intercept( + { + method: 'PUT', + url: 'https://smile-uploads-development01.s3.us-west-2.amazonaws.com/videos/212/212-0000060103-0gdzke3mdtlco5k0sdfh6vifzcrd3n/smartselfie.zip', + }, + { + statusCode: 412, + }, + ).as('failedUploadRequest'); + cy.navigateThroughNewCameraScreens(); + }); + + it('should show the upload failure screen', () => { + cy.wait('@getUploadURL'); + + cy.getIFrameBody() + .find('#upload-progress-screen') + .should('not.be.visible'); + + cy.wait('@failedUploadRequest'); + + cy.getIFrameBody().find('#upload-failure-screen').should('be.visible'); + }); + + it('should should retry upload when "try again" button is clicked', () => { + cy.wait('@getUploadURL'); + + cy.wait('@failedUploadRequest'); + + cy.getIFrameBody().find('#retry-upload').click(); + + cy.wait('@failedUploadRequest'); + }); + }); +}); diff --git a/packages/embed/package.json b/packages/embed/package.json index 22246a90..22343f32 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -1,6 +1,6 @@ { "name": "@smileid/embed", - "version": "1.3.7", + "version": "1.3.8", "description": "Self Hosted Integration for Smile Identity on the Web", "private": true, "main": "inline.js", diff --git a/packages/embed/src/js/basic-kyc.js b/packages/embed/src/js/basic-kyc.js index 7fc5b8ee..5ec79a96 100644 --- a/packages/embed/src/js/basic-kyc.js +++ b/packages/embed/src/js/basic-kyc.js @@ -171,6 +171,15 @@ import { version as sdkVersion } from '../../package.json'; } function initializeSession(generalConstraints, partnerConstraints) { + if (hasThemeColor()) { + const root = document.documentElement; + + root.style.setProperty( + '--color-default', + config.partner_details.theme_color, + ); + } + const supportedCountries = Object.keys(generalConstraints) .map((countryCode) => ({ code: countryCode, @@ -322,6 +331,14 @@ import { version as sdkVersion } from '../../package.json'; document.body.appendChild(script); } + function hasThemeColor() { + return ( + config.partner_details.theme_color && + ![null, undefined, 'null', 'undefined'].includes( + config.partner_details.theme_color, + ) + ); + } IDInfoForm.querySelector('#submitForm').addEventListener( 'click', (event) => { diff --git a/packages/embed/src/js/biometric-kyc.js b/packages/embed/src/js/biometric-kyc.js index 4d3663e1..b3b0d8a5 100644 --- a/packages/embed/src/js/biometric-kyc.js +++ b/packages/embed/src/js/biometric-kyc.js @@ -177,10 +177,20 @@ import { version as sdkVersion } from '../../package.json'; } function initializeSession(generalConstraints, partnerConstraints) { - SmartCameraWeb.setAttribute( - 'theme-color', - config.partner_details.theme_color, - ); + if (hasThemeColor()) { + SmartCameraWeb.setAttribute( + 'theme-color', + config.partner_details.theme_color, + ); + + const root = document.documentElement; + + root.style.setProperty( + '--color-default', + config.partner_details.theme_color, + ); + } + const supportedCountries = Object.keys(generalConstraints) .map((countryCode) => ({ code: countryCode, @@ -333,6 +343,15 @@ import { version as sdkVersion } from '../../package.json'; document.body.appendChild(script); } + function hasThemeColor() { + return ( + config.partner_details.theme_color && + ![null, undefined, 'null', 'undefined'].includes( + config.partner_details.theme_color, + ) + ); + } + SmartCameraWeb.addEventListener( 'imagesComputed', (event) => { diff --git a/packages/embed/src/js/doc-verification.js b/packages/embed/src/js/doc-verification.js index e2aa73e7..08988dbe 100644 --- a/packages/embed/src/js/doc-verification.js +++ b/packages/embed/src/js/doc-verification.js @@ -209,10 +209,19 @@ import { version as sdkVersion } from '../../package.json'; let selectedIdType; let selectedIdName; - SmartCameraWeb.setAttribute( - 'theme-color', - config.partner_details.theme_color, - ); + if (hasThemeColor()) { + SmartCameraWeb.setAttribute( + 'theme-color', + config.partner_details.theme_color, + ); + + const root = document.documentElement; + + root.style.setProperty( + '--color-default', + config.partner_details.theme_color, + ); + } function loadIdTypes(countryCode) { const countryIdTypes = constraints.find( @@ -443,6 +452,15 @@ import { version as sdkVersion } from '../../package.json'; } } + function hasThemeColor() { + return ( + config.partner_details.theme_color && + ![null, undefined, 'null', 'undefined'].includes( + config.partner_details.theme_color, + ) + ); + } + SmartCameraWeb.addEventListener( 'imagesComputed', (event) => { diff --git a/packages/embed/src/js/ekyc.js b/packages/embed/src/js/ekyc.js index 9c2f80eb..f539c324 100644 --- a/packages/embed/src/js/ekyc.js +++ b/packages/embed/src/js/ekyc.js @@ -169,6 +169,14 @@ import { version as sdkVersion } from '../../package.json'; } function initializeSession(generalConstraints, partnerConstraints) { + if (hasThemeColor()) { + const root = document.documentElement; + + root.style.setProperty( + '--color-default', + config.partner_details.theme_color, + ); + } const supportedCountries = Object.keys(generalConstraints) .map((countryCode) => ({ code: countryCode, @@ -321,6 +329,15 @@ import { version as sdkVersion } from '../../package.json'; document.body.appendChild(script); } + function hasThemeColor() { + return ( + config.partner_details.theme_color && + ![null, undefined, 'null', 'undefined'].includes( + config.partner_details.theme_color, + ) + ); + } + IDInfoForm.querySelector('#submitForm').addEventListener( 'click', (event) => { diff --git a/packages/embed/src/js/enhanced-document-verification.js b/packages/embed/src/js/enhanced-document-verification.js index 2abfccfe..caca5a4e 100644 --- a/packages/embed/src/js/enhanced-document-verification.js +++ b/packages/embed/src/js/enhanced-document-verification.js @@ -78,10 +78,19 @@ import { version as sdkVersion } from '../../package.json'; ); function initializeSession(constraints) { - SmartCameraWeb.setAttribute( - 'theme-color', - config.partner_details.theme_color, - ); + if (hasThemeColor()) { + SmartCameraWeb.setAttribute( + 'theme-color', + config.partner_details.theme_color, + ); + + const root = document.documentElement; + + root.style.setProperty( + '--color-default', + config.partner_details.theme_color, + ); + } const supportedCountries = Object.keys(constraints) .map((countryCode) => ({ code: countryCode, @@ -253,6 +262,15 @@ import { version as sdkVersion } from '../../package.json'; document.body.appendChild(script); } + function hasThemeColor() { + return ( + config.partner_details.theme_color && + ![null, undefined, 'null', 'undefined'].includes( + config.partner_details.theme_color, + ) + ); + } + SmartCameraWeb.addEventListener( 'imagesComputed', (event) => { diff --git a/packages/embed/src/js/smartselfie-auth.js b/packages/embed/src/js/smartselfie-auth.js index d1ebc5f0..f5f91e4a 100644 --- a/packages/embed/src/js/smartselfie-auth.js +++ b/packages/embed/src/js/smartselfie-auth.js @@ -1,4 +1,3 @@ -import '@smile_identity/smart-camera-web'; import JSZip from 'jszip'; import { version as sdkVersion } from '../../package.json'; @@ -57,6 +56,12 @@ import { version as sdkVersion } from '../../package.json'; event.data.includes('SmileIdentity::Configuration') ) { config = JSON.parse(event.data); + if (config.use_new_component) { + import('@smileid/web-components/smart-camera-web'); + CloseIframeButton.setAttribute('hidden', true); + } else { + import('@smile_identity/smart-camera-web'); + } partner_params = getPartnerParams(); id_info = {}; SmartCameraWeb.setAttribute( @@ -81,6 +86,16 @@ import { version as sdkVersion } from '../../package.json'; false, ); + SmartCameraWeb.addEventListener( + 'smart-camera-web.publish', + (event) => { + images = event.detail.images; + setActiveScreen(UploadProgressScreen); + handleFormSubmit(event); + }, + false, + ); + RetryUploadButton.addEventListener( 'click', () => { @@ -89,7 +104,7 @@ import { version as sdkVersion } from '../../package.json'; false, ); - CloseIframeButton.addEventListener( + CloseIframeButton?.addEventListener( 'click', () => { closeWindow(true); @@ -97,6 +112,22 @@ import { version as sdkVersion } from '../../package.json'; false, ); + SmartCameraWeb.addEventListener( + 'smart-camera-web.close', + () => { + closeWindow(true); + }, + false, + ); + + SmartCameraWeb.addEventListener( + 'smart-camera-web.cancelled', + () => { + closeWindow(true); + }, + false, + ); + function parseJWT(token) { /** * A JSON Web Token (JWT) uses a base64 URL encoded string in it's body. diff --git a/packages/smart-camera-web/package.json b/packages/smart-camera-web/package.json index fd07578f..1d0469fb 100644 --- a/packages/smart-camera-web/package.json +++ b/packages/smart-camera-web/package.json @@ -1,6 +1,6 @@ { "name": "@smile_identity/smart-camera-web", - "version": "1.3.7", + "version": "1.3.8", "description": "WebComponent for smartly capturing images on the web, for use with SmileIdentity", "main": "smart-camera-web.js", "scripts": { diff --git a/packages/web-components/components/selfie/src/SelfieCaptureScreens.js b/packages/web-components/components/selfie/src/SelfieCaptureScreens.js index 7a66d51b..b8cd5ac8 100644 --- a/packages/web-components/components/selfie/src/SelfieCaptureScreens.js +++ b/packages/web-components/components/selfie/src/SelfieCaptureScreens.js @@ -30,7 +30,7 @@ class SelfieCaptureScreens extends HTMLElement { ${styles(this.themeColor)}
- +
`; @@ -167,6 +167,18 @@ class SelfieCaptureScreens extends HTMLElement { return this.hasAttribute('show-navigation') ? 'show-navigation' : ''; } + get allowAgentMode() { + return this.hasAttribute('allow-agent-mode') + ? "allow-agent-mode='true'" + : ''; + } + + get allowAgentModeTests() { + return this.hasAttribute('show-agent-mode-for-tests') + ? 'show-agent-mode-for-tests' + : ''; + } + get hideBack() { return this.hasAttribute('hide-back-to-host') ? 'hide-back' : ''; } diff --git a/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.js b/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.js index a66aaf60..65828d91 100644 --- a/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.js +++ b/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.js @@ -387,6 +387,11 @@ function templateString() { transform: scaleX(-1) translateX(50%) translateY(-50%); } + .video-container video.agent-mode { + min-height: 100%; + transform: scaleX(1) translateX(-50%) translateY(-50%); + } + .video-container .video { background-color: black; position: absolute; @@ -526,27 +531,26 @@ function templateString() { Tips: Put your face inside the oval frame and click to "take selfie" + ${this.allowAgentMode ? `` : ''} + - ${ - this.hideAttribution - ? '' - : ` - - ` - } + ${this.hideAttribution ? '' : ''} `; } -async function getPermissions(captureScreen) { +async function getPermissions( + captureScreen, + constraints = { facingMode: 'user' }, +) { try { await SmartCamera.getMedia({ audio: false, - video: true, + video: constraints, }); captureScreen?.removeAttribute('data-camera-error'); captureScreen?.setAttribute('data-camera-ready', true); @@ -566,12 +570,16 @@ class SelfieCaptureScreen extends HTMLElement { this.render = () => this.templateString(); this.attachShadow({ mode: 'open' }); + this.facingMode = 'user'; + if (this.allowAgentMode) { + this.facingMode = 'environment'; + } } connectedCallback() { const template = document.createElement('template'); template.innerHTML = this.render(); - + this.shadowRoot.innerHTML = ''; this.shadowRoot.appendChild(template.content.cloneNode(true)); this.videoContainer = this.shadowRoot.querySelector( '.video-container > .video', @@ -601,6 +609,9 @@ class SelfieCaptureScreen extends HTMLElement { _startImageCapture() { this.startImageCapture.disabled = true; + if (this.switchCamera) { + this.switchCamera.disabled = true; + } /** * this was culled from https://jakearchibald.com/2013/animated-line-drawing-svg/ @@ -631,6 +642,15 @@ class SelfieCaptureScreen extends HTMLElement { }, this._videoStreamDurationInMS); } + async _switchCamera() { + this.facingMode = this.facingMode === 'user' ? 'environment' : 'user'; + this.startImageCapture.disabled = true; + this.switchCamera.disabled = true; + SmartCamera.stopMedia(); + await getPermissions(this, { facingMode: this.facingMode }); + this.handleStream(SmartCamera.stream); + } + _stopVideoStream() { try { clearTimeout(this._videoStreamTimeout); @@ -746,6 +766,10 @@ class SelfieCaptureScreen extends HTMLElement { video = document.createElement('video'); } + if (this.facingMode === 'environment') { + video.classList.add('agent-mode'); + } + video.autoplay = true; video.playsInline = true; video.muted = true; @@ -782,6 +806,8 @@ class SelfieCaptureScreen extends HTMLElement { this.startImageCapture = this.shadowRoot.querySelector( '#start-image-capture', ); + + this.switchCamera = this.shadowRoot.querySelector('#switch-camera'); this.imageOutline = this.shadowRoot.querySelector('#image-outline path'); this.smileCTA = this.shadowRoot.querySelector('#smile-cta'); @@ -789,6 +815,10 @@ class SelfieCaptureScreen extends HTMLElement { this._startImageCapture(); }); + this.switchCamera?.addEventListener('click', () => { + this._switchCamera(); + }); + this.navigation.addEventListener('navigation.back', () => { this.handleBackEvents(); }); @@ -800,8 +830,10 @@ class SelfieCaptureScreen extends HTMLElement { if (SmartCamera.stream) { this.handleStream(SmartCamera.stream); } else if (this.hasAttribute('data-camera-ready')) { - getPermissions(this); + getPermissions(this, { facingMode: this.facingMode }); } + + this.setupAgentMode(); } disconnectedCallback() { @@ -825,9 +857,46 @@ class SelfieCaptureScreen extends HTMLElement { return this.hasAttribute('hide-attribution'); } - get supportBothCaptureModes() { - const value = this.documentCaptureModes; - return value.includes('camera') && value.includes('upload'); + async setupAgentMode() { + if (!this.allowAgentMode) { + return; + } + + const supportAgentMode = await this.supportsAgentMode(); + + if (supportAgentMode || this.hasAttribute('show-agent-mode-for-tests')) { + this.switchCamera.hidden = false; + } else { + this.switchCamera.hidden = true; + } + } + + async supportsAgentMode() { + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + const videoDevices = devices.filter( + (device) => device.kind === 'videoinput', + ); + + let hasBackCamera = false; + + videoDevices.forEach((device) => { + // Check if the device label or device ID indicates a back camera + if ( + device.label.toLowerCase().includes('back') || + device.label.toLowerCase().includes('rear') + ) { + hasBackCamera = true; + return true; + } + return false; + }); + + return hasBackCamera; + } catch (error) { + console.warn('Error accessing media devices: ', error); + return false; + } } get title() { @@ -846,10 +915,20 @@ class SelfieCaptureScreen extends HTMLElement { return this.hasAttribute('disable-image-tests'); } + get allowAgentMode() { + return this.getAttribute('allow-agent-mode') === 'true'; + } + + get inAgentMode() { + return this.facingMode === 'environment'; + } + static get observedAttributes() { return [ + 'allow-agent-mode', 'data-camera-error', 'data-camera-ready', + 'disable-image-tests', 'hidden', 'hide-back-to-host', 'show-navigation', @@ -863,6 +942,7 @@ class SelfieCaptureScreen extends HTMLElement { case 'data-camera-ready': case 'hidden': case 'title': + case 'allow-agent-mode': this.shadowRoot.innerHTML = this.render(); this.init(); break; diff --git a/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.stories.js b/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.stories.js index 4a09c2f6..7d7089bd 100644 --- a/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.stories.js +++ b/packages/web-components/components/selfie/src/selfie-capture/SelfieCapture.stories.js @@ -27,3 +27,10 @@ export const SelfieCapture = { `, }; + +export const SelfieCaptureAgentMode = { + render: () => ` + + + `, +}; diff --git a/packages/web-components/components/signature-pad/package.json b/packages/web-components/components/signature-pad/package.json index e2ff02cf..d32270a9 100644 --- a/packages/web-components/components/signature-pad/package.json +++ b/packages/web-components/components/signature-pad/package.json @@ -1,6 +1,6 @@ { "name": "@smileid/signature-pad", - "version": "1.3.7", + "version": "1.3.8", "private": "true", "exports": { ".": "./index.js" diff --git a/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.js b/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.js index 74eb2356..3449f2e3 100644 --- a/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.js +++ b/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.js @@ -13,7 +13,7 @@ function scwTemplateString() {
@@ -61,8 +61,10 @@ class SmartCameraWeb extends HTMLElement { static get observedAttributes() { return [ + 'disable-image-tests', 'document-capture-modes', 'document-type', + 'hide-back-of-id', 'hide-back-to-host', 'show-navigation', 'hide-back-of-id', @@ -72,6 +74,7 @@ class SmartCameraWeb extends HTMLElement { attributeChangedCallback(name) { switch (name) { + case 'disable-image-tests': case 'document-capture-modes': case 'document-type': case 'hide-back-of-id': @@ -219,6 +222,18 @@ class SmartCameraWeb extends HTMLElement { return this.hasAttribute('hide-back-to-host') ? 'hide-back-to-host' : ''; } + get allowAgentMode() { + return this.hasAttribute('allow-agent-mode') + ? `allow-agent-mode=${this.getAttribute('allow-agent-mode')}` + : ''; + } + + get allowAgentModeTests() { + return this.hasAttribute('show-agent-mode-for-tests') + ? 'show-agent-mode-for-tests' + : ''; + } + get title() { return this.hasAttribute('title') ? `title=${this.getAttribute('title')}` diff --git a/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.stories.js b/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.stories.js index 8a572396..9fd85eb1 100644 --- a/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.stories.js +++ b/packages/web-components/components/smart-camera-web/src/SmartCameraWeb.stories.js @@ -46,3 +46,10 @@ export const SmartCameraWebWithOutBackId = { `, }; + +export const SmartCameraWebAgentMode = { + render: () => ` + + + `, +}; diff --git a/packages/web-components/cypress/e2e/smart-camera-web-agent-mode.cy.js b/packages/web-components/cypress/e2e/smart-camera-web-agent-mode.cy.js new file mode 100644 index 00000000..cd64a703 --- /dev/null +++ b/packages/web-components/cypress/e2e/smart-camera-web-agent-mode.cy.js @@ -0,0 +1,83 @@ +context('SmartCameraWeb', () => { + beforeEach(() => { + cy.visit('/smart-camera-web-agent-mode'); + }); + it('should switch from the selfie mode to agent mode"', () => { + cy.log('Enable agent mode for tests'); + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .invoke('attr', 'show-agent-mode-for-tests', 'true'); + + cy.clock(); + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture-instructions') + .shadow() + .find('#allow') + .click(); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .should('be.visible'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('contain.text', 'Agent Mode On'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .find('#switch-camera') + .click(); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('contain.text', 'Agent Mode Off'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .find('#switch-camera') + .click(); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('contain.text', 'Agent Mode On'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('contain.text', 'Take a Selfie'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .find('#start-image-capture') + .click(); + + cy.tick(8000); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture') + .shadow() + .should('not.be.visible'); + + cy.get('smart-camera-web') + .shadow() + .find('selfie-capture-review') + .should('be.visible'); + }); +}); diff --git a/packages/web-components/cypress/e2e/smart-camera-web.cy.js b/packages/web-components/cypress/e2e/smart-camera-web.cy.js index 2daac891..8a28019a 100644 --- a/packages/web-components/cypress/e2e/smart-camera-web.cy.js +++ b/packages/web-components/cypress/e2e/smart-camera-web.cy.js @@ -271,7 +271,7 @@ context('SmartCameraWeb', () => { .should('not.be.visible'); }); - it('should switch to request screen when "Rest"', () => { + it('should switch to request screen when "Reset"', () => { cy.get('smart-camera-web').then((element) => { element[0].reset(); }); diff --git a/packages/web-components/cypress/pages/smart-camera-web-agent-mode.html b/packages/web-components/cypress/pages/smart-camera-web-agent-mode.html new file mode 100644 index 00000000..e87fa1a5 --- /dev/null +++ b/packages/web-components/cypress/pages/smart-camera-web-agent-mode.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/packages/web-components/package.json b/packages/web-components/package.json index b30d5387..75c0b250 100644 --- a/packages/web-components/package.json +++ b/packages/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@smileid/web-components", - "version": "1.3.7", + "version": "1.3.8", "private": "true", "exports": { ".": "./index.js",