@smileid/web-components 1.0.0-beta → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/components/README.md +1 -1
- package/components/camera-permission/CameraPermission.js +6 -2
- package/components/camera-permission/CameraPermission.stories.js +10 -4
- package/components/document/src/DocumentCaptureScreens.js +41 -11
- package/components/document/src/DocumentCaptureScreens.stories.js +16 -12
- package/components/document/src/README.md +11 -8
- package/components/document/src/document-capture/DocumentCapture.js +299 -231
- package/components/document/src/document-capture/DocumentCapture.stories.js +9 -2
- package/components/document/src/document-capture/README.md +5 -4
- package/components/document/src/document-capture-instructions/DocumentCaptureInstructions.js +33 -33
- package/components/document/src/document-capture-instructions/DocumentCaptureInstructions.stories.js +8 -1
- package/components/document/src/document-capture-review/DocumentCaptureReview.js +15 -31
- package/components/document/src/document-capture-review/DocumentCaptureReview.stories.js +12 -2
- package/components/document/src/document-capture-review/README.md +3 -3
- package/components/end-user-consent/src/EndUserConsent.js +14 -31
- package/components/end-user-consent/src/EndUserConsent.stories.js +8 -2
- package/components/navigation/src/Navigation.js +10 -2
- package/components/selfie/README.md +28 -4
- package/components/selfie/src/SelfieCaptureScreens.js +36 -10
- package/components/selfie/src/SelfieCaptureScreens.stories.js +13 -4
- package/components/selfie/src/selfie-capture/SelfieCapture.js +95 -23
- package/components/selfie/src/selfie-capture/SelfieCapture.stories.js +14 -1
- package/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.js +50 -44
- package/components/selfie/src/selfie-capture-instructions/SelfieCaptureInstructions.stories.js +8 -2
- package/components/selfie/src/selfie-capture-review/SelfieCaptureReview.js +3 -4
- package/components/selfie/src/selfie-capture-review/SelfieCaptureReview.stories.js +8 -1
- package/components/signature-pad/package-lock.json +3009 -0
- package/components/signature-pad/package.json +6 -6
- package/components/signature-pad/src/SignaturePad.js +5 -1
- package/components/signature-pad/src/SignaturePad.stories.js +10 -2
- package/components/smart-camera-web/src/README.md +207 -0
- package/components/smart-camera-web/src/SmartCameraWeb.js +56 -7
- package/components/smart-camera-web/src/SmartCameraWeb.stories.js +27 -7
- package/components/totp-consent/src/TotpConsent.js +15 -3
- package/cypress/e2e/smart-camera-web-agent-mode.cy.js +144 -0
- package/cypress/e2e/smart-camera-web-complete-flow.cy.js +221 -0
- package/cypress/e2e/smart-camera-web.cy.js +1 -1
- package/cypress/pages/smart-camera-web-agent-mode.html +36 -0
- package/cypress/pages/smart-camera-web-complete-flow.html +42 -0
- package/cypress/pages/smart-camera-web.html +1 -1
- package/domain/camera/src/SmartCamera.js +28 -0
- package/package.json +8 -8
- package/styles/src/styles.js +14 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smileid/signature-pad",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"private": "true",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js"
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": "SmileID <support@usesmileid.com> (https://usesmileid.com)",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"signature_pad": "^
|
|
18
|
+
"signature_pad": "^5.0.2"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"eslint": "^8.57.0",
|
|
22
22
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
23
23
|
"eslint-config-prettier": "^9.1.0",
|
|
24
|
-
"eslint-plugin-cypress": "^
|
|
24
|
+
"eslint-plugin-cypress": "^3.3.0",
|
|
25
25
|
"eslint-plugin-import": "^2.29.1",
|
|
26
|
-
"eslint-plugin-jest": "^28.
|
|
27
|
-
"eslint-plugin-prettier": "^5.1
|
|
28
|
-
"prettier": "^3.
|
|
26
|
+
"eslint-plugin-jest": "^28.6.0",
|
|
27
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
28
|
+
"prettier": "^3.3.3"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -177,7 +177,7 @@ button[data-variant="text"] {
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
button[data-variant="solid"] {
|
|
180
|
-
--button-color:
|
|
180
|
+
--button-color: ${this.themeColor};
|
|
181
181
|
border-radius: 2.5rem;
|
|
182
182
|
border: 0;
|
|
183
183
|
background-color: transparent;
|
|
@@ -468,6 +468,10 @@ button:disabled {
|
|
|
468
468
|
get allowUpload() {
|
|
469
469
|
return this.hasAttribute('allow-upload');
|
|
470
470
|
}
|
|
471
|
+
|
|
472
|
+
get themeColor() {
|
|
473
|
+
return this.getAttribute('theme-color') || '#001096';
|
|
474
|
+
}
|
|
471
475
|
}
|
|
472
476
|
|
|
473
477
|
if ('customElements' in window) {
|
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
import './SignaturePad';
|
|
2
2
|
|
|
3
3
|
const meta = {
|
|
4
|
+
args: {
|
|
5
|
+
'theme-color': '#001096',
|
|
6
|
+
},
|
|
7
|
+
argTypes: {
|
|
8
|
+
'theme-color': { control: 'color' },
|
|
9
|
+
},
|
|
4
10
|
component: 'smileid-signature-pad',
|
|
5
11
|
};
|
|
6
12
|
|
|
7
13
|
export default meta;
|
|
8
14
|
|
|
9
15
|
export const SignaturePad = {
|
|
10
|
-
render: () => `
|
|
16
|
+
render: (args) => `
|
|
11
17
|
<smileid-signature-pad
|
|
18
|
+
theme-color='${args['theme-color']}'
|
|
12
19
|
>
|
|
13
20
|
</smileid-signature-pad>
|
|
14
21
|
`,
|
|
15
22
|
};
|
|
16
23
|
|
|
17
24
|
export const SignaturePadWithUploads = {
|
|
18
|
-
render: () => `
|
|
25
|
+
render: (args) => `
|
|
19
26
|
<smileid-signature-pad
|
|
20
27
|
allow-upload
|
|
28
|
+
theme-color='${args['theme-color']}'
|
|
21
29
|
>
|
|
22
30
|
</smileid-signature-pad>
|
|
23
31
|
`,
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# SmartCameraWeb
|
|
2
|
+
|
|
3
|
+
`SmartCameraWeb` is a [Web Component](https://developer.mozilla.org/en-US/docs/Web/Web_Components) designed to capture images including selfies, liveness images, and ID Document images for use with SmileIdentity. It interfaces with the [Server to Server](https://docs.usesmileid.com/server-to-server) libraries, serving as a user interface client.
|
|
4
|
+
|
|
5
|
+
Explore an [example full stack integration](https://glitch.com/edit/#!/smart-camera-web-demo-node) using our [NodeJS](https://docs.usesmileid.com/server-to-server/javascript) library.
|
|
6
|
+
|
|
7
|
+
## Getting Started
|
|
8
|
+
|
|
9
|
+
To integrate `SmartCameraWeb`, follow these steps:
|
|
10
|
+
|
|
11
|
+
- [SmartCameraWeb](#smartcameraweb)
|
|
12
|
+
- [Getting Started](#getting-started)
|
|
13
|
+
- [Choose a Server to Server Library](#choose-a-server-to-server-library)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Install Via NPM](#install-via-npm)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Compatibility](#compatibility)
|
|
18
|
+
- [Support](#support)
|
|
19
|
+
- [Development](#development)
|
|
20
|
+
|
|
21
|
+
### Choose a Server to Server Library
|
|
22
|
+
|
|
23
|
+
Supported [Server to Server Libraries](https://docs.usesmileid.com/server-to-server) include:
|
|
24
|
+
|
|
25
|
+
- [Java](https://docs.usesmileid.com/server-to-server/java)
|
|
26
|
+
- [NodeJS](https://docs.usesmileid.com/server-to-server/javascript)
|
|
27
|
+
- [PHP](https://docs.usesmileid.com/server-to-server/php)
|
|
28
|
+
- [Python](https://docs.usesmileid.com/server-to-server/python)
|
|
29
|
+
- [Ruby](https://docs.usesmileid.com/server-to-server/ruby)
|
|
30
|
+
|
|
31
|
+
> **Note**: Code samples in this documentation utilize the NodeJS Server to Server library.
|
|
32
|
+
|
|
33
|
+
### Installation
|
|
34
|
+
|
|
35
|
+
You can install via NPM or directly include it from our CDN.
|
|
36
|
+
|
|
37
|
+
#### Install Via NPM
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
npm install @smileid/web-components@<version>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then, in your VueJS, AngularJS, or React component:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
import '@smileid/web-components/smart-camera-web';
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Usage
|
|
50
|
+
|
|
51
|
+
After installation and necessary imports:
|
|
52
|
+
|
|
53
|
+
1. Add the desired markup to your page/component:
|
|
54
|
+
|
|
55
|
+
- **For Selfie Capture / Liveness Images**:
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<smart-camera-web></smart-camera-web>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- **For Selfie Capture / Liveness and ID Images**:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<smart-camera-web capture-id></smart-camera-web>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Initially, you'll see this image:
|
|
68
|
+

|
|
69
|
+
|
|
70
|
+
After granting access, the capture screen appears:
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
Upon capturing a selfie, you'll reach the review screen:
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+

|
|
77
|
+
|
|
78
|
+
If the `capture-id` attribute is used, additional screens include:
|
|
79
|
+
|
|
80
|
+

|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
2. Handle the `smart-camera-web.publish` event:
|
|
85
|
+
|
|
86
|
+
When the user approves the captured image, an `smart-camera-web.publish` event is dispatched. The event returns a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent) payload in `e.detail`.
|
|
87
|
+
|
|
88
|
+
Here's a script example to handle the event and send data to a backend endpoint:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<script>
|
|
92
|
+
const app = document.querySelector('smart-camera-web');
|
|
93
|
+
|
|
94
|
+
const postContent = async (data) => {
|
|
95
|
+
const options = {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: {
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify(data),
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const response = await fetch('/', options);
|
|
105
|
+
const json = await response.json();
|
|
106
|
+
|
|
107
|
+
return json;
|
|
108
|
+
} catch (e) {
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
app.addEventListener('smart-camera-web.publish', async (e) => {
|
|
114
|
+
try {
|
|
115
|
+
const response = await postContent(e.detail);
|
|
116
|
+
|
|
117
|
+
console.log(response);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error(e);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
</script>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The provided backend endpoint uses the NodeJS Server to Server library and ExpressJS:
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
const express = require('express');
|
|
129
|
+
const { v4: UUID } = require('uuid');
|
|
130
|
+
|
|
131
|
+
if (process.env.NODE_ENV === 'development') {
|
|
132
|
+
const dotenv = require('dotenv');
|
|
133
|
+
|
|
134
|
+
dotenv.config();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const SIDCore = require('smile-identity-core');
|
|
138
|
+
const SIDSignature = SIDCore.Signature;
|
|
139
|
+
const SIDWebAPI = SIDCore.WebApi;
|
|
140
|
+
|
|
141
|
+
const app = express();
|
|
142
|
+
|
|
143
|
+
app.use(express.json({ limit: '500kb' }));
|
|
144
|
+
app.use(express.static('public'));
|
|
145
|
+
|
|
146
|
+
app.post('/', async (req, res, next) => {
|
|
147
|
+
try {
|
|
148
|
+
const { PARTNER_ID, API_KEY, SID_SERVER } = process.env;
|
|
149
|
+
const connection = new SIDWebAPI(
|
|
150
|
+
PARTNER_ID,
|
|
151
|
+
'/callback',
|
|
152
|
+
API_KEY,
|
|
153
|
+
SID_SERVER,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
const partner_params_from_server = {
|
|
157
|
+
user_id: `user-${UUID()}`,
|
|
158
|
+
job_id: `job-${UUID()}`,
|
|
159
|
+
job_type: 4, // job_type is the simplest job we have which enrolls a user using their selfie
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const {
|
|
163
|
+
images,
|
|
164
|
+
partner_params: { libraryVersion },
|
|
165
|
+
} = req.body;
|
|
166
|
+
|
|
167
|
+
const options = {
|
|
168
|
+
return_job_status: true,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const partner_params = Object.assign({}, partner_params_from_server, {
|
|
172
|
+
libraryVersion,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const result = await connection.submit_job(
|
|
176
|
+
partner_params,
|
|
177
|
+
images,
|
|
178
|
+
{},
|
|
179
|
+
options,
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
res.json(result);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
console.error(e);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// NOTE: This can be used to process responses. don't forget to add it as a callback option in the `connection` config on L22
|
|
189
|
+
// https://docs.usesmileid.com/further-reading/faqs/how-do-i-setup-a-callback
|
|
190
|
+
app.post('/callback', (req, res, next) => {});
|
|
191
|
+
|
|
192
|
+
app.listen(process.env.PORT || 4000);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
This approach can also be achieved using other Server to Server libraries.
|
|
196
|
+
|
|
197
|
+
## Compatibility
|
|
198
|
+
|
|
199
|
+
`SmartCameraWeb` is compatible with most JavaScript frameworks and libraries. For integration with [ReactJS](https://reactjs.org), refer to this [tutorial](https://www.robinwieruch.de/react-web-components) due to React-WebComponents compatibility issues.
|
|
200
|
+
|
|
201
|
+
## Support
|
|
202
|
+
|
|
203
|
+
Tested on the latest versions of Chrome, Edge, Firefox, and Safari. If compatibility issues arise on certain browsers, please notify us.
|
|
204
|
+
|
|
205
|
+
## Development
|
|
206
|
+
|
|
207
|
+
Note: `smart-camera-web.js` is generated from `src/` using [esbuild](https://esbuild.github.io/). To make changes, edit the source files and run `npm run build` to generate the new `smart-camera-web.js` file.
|
|
@@ -9,13 +9,14 @@ import { version as COMPONENTS_VERSION } from '../../../package.json';
|
|
|
9
9
|
|
|
10
10
|
function scwTemplateString() {
|
|
11
11
|
return `
|
|
12
|
-
${styles}
|
|
12
|
+
${styles(this.themeColor)}
|
|
13
13
|
<div>
|
|
14
|
-
<camera-permission ${this.title} ${this.showNavigation} ${this.hideInstructions ? '' : 'hidden'}></camera-permission>
|
|
15
|
-
<selfie-capture-screens ${this.title} ${this.showNavigation} ${this.disableImageTests} ${this.hideAttribution} ${this.hideInstructions} hidden
|
|
16
|
-
${this.hideBackToHost}
|
|
14
|
+
<camera-permission ${this.applyComponentThemeColor} ${this.title} ${this.showNavigation} ${this.hideInstructions ? '' : 'hidden'} ${this.hideAttribution}></camera-permission>
|
|
15
|
+
<selfie-capture-screens ${this.applyComponentThemeColor} ${this.title} ${this.showNavigation} ${this.disableImageTests} ${this.hideAttribution} ${this.hideInstructions} hidden
|
|
16
|
+
${this.hideBackToHost} ${this.allowAgentMode} ${this.allowAgentModeTests}
|
|
17
17
|
></selfie-capture-screens>
|
|
18
|
-
<document-capture-screens document-type=${this.documentType} ${this.title} ${this.documentCaptureModes} ${this.showNavigation} ${this.hideAttribution}
|
|
18
|
+
<document-capture-screens ${this.applyComponentThemeColor} document-type=${this.documentType} ${this.title} ${this.documentCaptureModes} ${this.showNavigation} ${this.hideAttribution}
|
|
19
|
+
${this.hideBackOfId} ${this.applyComponentThemeColor} hidden></document-capture-screens>
|
|
19
20
|
</div>
|
|
20
21
|
`;
|
|
21
22
|
}
|
|
@@ -60,19 +61,30 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
60
61
|
|
|
61
62
|
static get observedAttributes() {
|
|
62
63
|
return [
|
|
64
|
+
'allow-agent-mode',
|
|
65
|
+
'disable-image-tests',
|
|
63
66
|
'document-capture-modes',
|
|
64
67
|
'document-type',
|
|
68
|
+
'hide-attribution',
|
|
69
|
+
'hide-back-of-id',
|
|
65
70
|
'hide-back-to-host',
|
|
66
71
|
'show-navigation',
|
|
72
|
+
'theme-color',
|
|
67
73
|
];
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
attributeChangedCallback(name) {
|
|
71
77
|
switch (name) {
|
|
78
|
+
case 'allow-agent-mode':
|
|
79
|
+
case 'disable-image-tests':
|
|
72
80
|
case 'document-capture-modes':
|
|
73
81
|
case 'document-type':
|
|
82
|
+
case 'hide-attribution':
|
|
83
|
+
case 'hide-back-of-id':
|
|
74
84
|
case 'hide-back-to-host':
|
|
75
85
|
case 'show-navigation':
|
|
86
|
+
case 'theme-color':
|
|
87
|
+
this.disconnectedCallback();
|
|
76
88
|
this.shadowRoot.innerHTML = this.render();
|
|
77
89
|
this.setUpEventListeners();
|
|
78
90
|
break;
|
|
@@ -105,7 +117,11 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
105
117
|
'selfie-capture-screens.publish',
|
|
106
118
|
(event) => {
|
|
107
119
|
this._data.images = event.detail.images;
|
|
108
|
-
|
|
120
|
+
if (!this.captureId) {
|
|
121
|
+
this._publishSelectedImages();
|
|
122
|
+
} else {
|
|
123
|
+
this.setActiveScreen(this.documentCapture);
|
|
124
|
+
}
|
|
109
125
|
},
|
|
110
126
|
);
|
|
111
127
|
|
|
@@ -182,6 +198,10 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
182
198
|
);
|
|
183
199
|
}
|
|
184
200
|
|
|
201
|
+
get captureId() {
|
|
202
|
+
return this.hasAttribute('capture-id');
|
|
203
|
+
}
|
|
204
|
+
|
|
185
205
|
get documentType() {
|
|
186
206
|
return this.getAttribute('document-type');
|
|
187
207
|
}
|
|
@@ -195,7 +215,7 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
195
215
|
}
|
|
196
216
|
|
|
197
217
|
get hideBackOfId() {
|
|
198
|
-
return this.hasAttribute('hide-back-of-id');
|
|
218
|
+
return this.hasAttribute('hide-back-of-id') ? 'hide-back-of-id' : '';
|
|
199
219
|
}
|
|
200
220
|
|
|
201
221
|
get showNavigation() {
|
|
@@ -206,6 +226,18 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
206
226
|
return this.hasAttribute('hide-back-to-host') ? 'hide-back-to-host' : '';
|
|
207
227
|
}
|
|
208
228
|
|
|
229
|
+
get allowAgentMode() {
|
|
230
|
+
return this.hasAttribute('allow-agent-mode')
|
|
231
|
+
? `allow-agent-mode=${this.getAttribute('allow-agent-mode')}`
|
|
232
|
+
: '';
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get allowAgentModeTests() {
|
|
236
|
+
return this.hasAttribute('show-agent-mode-for-tests')
|
|
237
|
+
? 'show-agent-mode-for-tests'
|
|
238
|
+
: '';
|
|
239
|
+
}
|
|
240
|
+
|
|
209
241
|
get title() {
|
|
210
242
|
return this.hasAttribute('title')
|
|
211
243
|
? `title=${this.getAttribute('title')}`
|
|
@@ -228,6 +260,23 @@ class SmartCameraWeb extends HTMLElement {
|
|
|
228
260
|
return this.hasAttribute('hide-attribution') ? 'hide-attribution' : '';
|
|
229
261
|
}
|
|
230
262
|
|
|
263
|
+
get hasThemeColor() {
|
|
264
|
+
return (
|
|
265
|
+
this.hasAttribute('theme-color') &&
|
|
266
|
+
![null, undefined, 'null', 'undefined'].includes(
|
|
267
|
+
this.getAttribute('theme-color'),
|
|
268
|
+
)
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
get themeColor() {
|
|
273
|
+
return this.hasThemeColor ? this.getAttribute('theme-color') : '#001096';
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get applyComponentThemeColor() {
|
|
277
|
+
return this.hasThemeColor ? `theme-color='${this.themeColor}'` : '';
|
|
278
|
+
}
|
|
279
|
+
|
|
231
280
|
setActiveScreen(screen) {
|
|
232
281
|
this.activeScreen?.setAttribute('hidden', '');
|
|
233
282
|
screen.removeAttribute('hidden');
|
|
@@ -1,35 +1,55 @@
|
|
|
1
1
|
import './SmartCameraWeb';
|
|
2
2
|
|
|
3
3
|
const meta = {
|
|
4
|
+
args: {
|
|
5
|
+
'theme-color': '#001096',
|
|
6
|
+
},
|
|
7
|
+
argTypes: {
|
|
8
|
+
'theme-color': { control: 'color' },
|
|
9
|
+
},
|
|
4
10
|
component: 'smart-camera-web',
|
|
5
11
|
};
|
|
6
12
|
|
|
7
13
|
export default meta;
|
|
8
14
|
|
|
9
15
|
export const SmartCameraWeb = {
|
|
10
|
-
render: () => `
|
|
11
|
-
<smart-camera-web
|
|
16
|
+
render: (args) => `
|
|
17
|
+
<smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation>
|
|
12
18
|
</smart-camera-web>
|
|
13
19
|
`,
|
|
14
20
|
};
|
|
15
21
|
|
|
16
22
|
export const SmartCameraWebWithOutInstructions = {
|
|
17
|
-
render: () => `
|
|
18
|
-
<smart-camera-web hide-instructions>
|
|
23
|
+
render: (args) => `
|
|
24
|
+
<smart-camera-web theme-color='${args['theme-color']}' capture-id hide-instructions>
|
|
19
25
|
</smart-camera-web>
|
|
20
26
|
`,
|
|
21
27
|
};
|
|
22
28
|
|
|
23
29
|
export const SmartCameraWebWithOutNavigation = {
|
|
24
|
-
render: () => `
|
|
25
|
-
<smart-camera-web>
|
|
30
|
+
render: (args) => `
|
|
31
|
+
<smart-camera-web theme-color='${args['theme-color']}' capture-id>
|
|
26
32
|
</smart-camera-web>
|
|
27
33
|
`,
|
|
28
34
|
};
|
|
29
35
|
|
|
30
36
|
export const SmartCameraWebWithOutBackToHost = {
|
|
37
|
+
render: (args) => `
|
|
38
|
+
<smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-to-host>
|
|
39
|
+
</smart-camera-web>
|
|
40
|
+
`,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const SmartCameraWebWithOutBackId = {
|
|
44
|
+
render: (args) => `
|
|
45
|
+
<smart-camera-web theme-color='${args['theme-color']}' capture-id show-navigation hide-back-of-id>
|
|
46
|
+
</smart-camera-web>
|
|
47
|
+
`,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const SmartCameraWebAgentMode = {
|
|
31
51
|
render: () => `
|
|
32
|
-
<smart-camera-web
|
|
52
|
+
<smart-camera-web hide-instructions hide-back-of-id allow-agent-mode='true' show-agent-mode-for-tests>
|
|
33
53
|
</smart-camera-web>
|
|
34
54
|
`,
|
|
35
55
|
};
|
|
@@ -196,7 +196,7 @@ function markup() {
|
|
|
196
196
|
.back-button-text {
|
|
197
197
|
font-size: 11px;
|
|
198
198
|
line-height: 11px;
|
|
199
|
-
color: rgb(21, 31, 114);
|
|
199
|
+
color: ${this.themeColor || 'rgb(21, 31, 114)'};
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
#error,
|
|
@@ -290,7 +290,7 @@ function markup() {
|
|
|
290
290
|
<button type='button' data-type='icon' id="back-button" class="back-button">
|
|
291
291
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none">
|
|
292
292
|
<path fill="#DBDBC4" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Z" opacity=".4"/>
|
|
293
|
-
<path fill="
|
|
293
|
+
<path fill="${this.themeColor}" d="M15.5 11.25h-5.19l1.72-1.72c.29-.29.29-.77 0-1.06a.754.754 0 0 0-1.06 0l-3 3c-.29.29-.29.77 0 1.06l3 3c.15.15.34.22.53.22s.38-.07.53-.22c.29-.29.29-.77 0-1.06l-1.72-1.72h5.19c.41 0 .75-.34.75-.75s-.34-.75-.75-.75Z"/>
|
|
294
294
|
</svg>
|
|
295
295
|
</button>
|
|
296
296
|
<div class="back-button-text">Back</div>
|
|
@@ -337,7 +337,7 @@ function markup() {
|
|
|
337
337
|
<button type='button' data-type='icon' id="back-to-entry-button" class="back-button">
|
|
338
338
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none">
|
|
339
339
|
<path fill="#DBDBC4" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Z" opacity=".4"/>
|
|
340
|
-
<path fill="
|
|
340
|
+
<path fill="${this.themeColor}" d="M15.5 11.25h-5.19l1.72-1.72c.29-.29.29-.77 0-1.06a.754.754 0 0 0-1.06 0l-3 3c-.29.29-.29.77 0 1.06l3 3c.15.15.34.22.53.22s.38-.07.53-.22c.29-.29.29-.77 0-1.06l-1.72-1.72h5.19c.41 0 .75-.34.75-.75s-.34-.75-.75-.75Z"/>
|
|
341
341
|
</svg>
|
|
342
342
|
</button>
|
|
343
343
|
<div class="back-button-text">Back</div>
|
|
@@ -893,6 +893,18 @@ class TotpConsent extends HTMLElement {
|
|
|
893
893
|
return this.getAttribute('token');
|
|
894
894
|
}
|
|
895
895
|
|
|
896
|
+
get themeColor() {
|
|
897
|
+
return this.getAttribute('theme-color') || '#001096';
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
get hideBack() {
|
|
901
|
+
return this.hasAttribute('hide-back');
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
get showNavigation() {
|
|
905
|
+
return this.hasAttribute('show-navigation');
|
|
906
|
+
}
|
|
907
|
+
|
|
896
908
|
handleTotpConsentGrant() {
|
|
897
909
|
const customEvent = new CustomEvent('end-user-consent.totp.granted', {
|
|
898
910
|
detail: {
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
context('SmartCameraWeb', () => {
|
|
2
|
+
beforeEach(() => {
|
|
3
|
+
cy.visit('/smart-camera-web-agent-mode');
|
|
4
|
+
});
|
|
5
|
+
|
|
6
|
+
it('should switch from the selfie mode to agent mode"', () => {
|
|
7
|
+
cy.log('Enable agent mode for tests');
|
|
8
|
+
cy.get('smart-camera-web')
|
|
9
|
+
.invoke('attr', 'allow-agent-mode', 'true')
|
|
10
|
+
.should('have.attr', 'allow-agent-mode', 'true');
|
|
11
|
+
|
|
12
|
+
cy.get('smart-camera-web').invoke(
|
|
13
|
+
'attr',
|
|
14
|
+
'show-agent-mode-for-tests',
|
|
15
|
+
'true',
|
|
16
|
+
);
|
|
17
|
+
cy.get('smart-camera-web').invoke('attr', 'disable-image-tests', '');
|
|
18
|
+
|
|
19
|
+
cy.clock();
|
|
20
|
+
cy.get('smart-camera-web')
|
|
21
|
+
.shadow()
|
|
22
|
+
.find('selfie-capture-instructions')
|
|
23
|
+
.shadow()
|
|
24
|
+
.find('#allow')
|
|
25
|
+
.click();
|
|
26
|
+
|
|
27
|
+
cy.get('smart-camera-web')
|
|
28
|
+
.shadow()
|
|
29
|
+
.find('selfie-capture')
|
|
30
|
+
.should('be.visible');
|
|
31
|
+
|
|
32
|
+
cy.get('smart-camera-web')
|
|
33
|
+
.shadow()
|
|
34
|
+
.find('selfie-capture')
|
|
35
|
+
.shadow()
|
|
36
|
+
.should('contain.text', 'Agent Mode On');
|
|
37
|
+
|
|
38
|
+
cy.get('smart-camera-web')
|
|
39
|
+
.shadow()
|
|
40
|
+
.find('selfie-capture')
|
|
41
|
+
.shadow()
|
|
42
|
+
.find('#switch-camera')
|
|
43
|
+
.click();
|
|
44
|
+
|
|
45
|
+
cy.get('smart-camera-web')
|
|
46
|
+
.shadow()
|
|
47
|
+
.find('selfie-capture')
|
|
48
|
+
.shadow()
|
|
49
|
+
.should('contain.text', 'Agent Mode Off');
|
|
50
|
+
|
|
51
|
+
cy.get('smart-camera-web')
|
|
52
|
+
.shadow()
|
|
53
|
+
.find('selfie-capture')
|
|
54
|
+
.shadow()
|
|
55
|
+
.find('#switch-camera')
|
|
56
|
+
.click();
|
|
57
|
+
|
|
58
|
+
cy.get('smart-camera-web')
|
|
59
|
+
.shadow()
|
|
60
|
+
.find('selfie-capture')
|
|
61
|
+
.shadow()
|
|
62
|
+
.should('contain.text', 'Agent Mode On');
|
|
63
|
+
|
|
64
|
+
cy.get('smart-camera-web')
|
|
65
|
+
.shadow()
|
|
66
|
+
.find('selfie-capture')
|
|
67
|
+
.shadow()
|
|
68
|
+
.should('contain.text', 'Take a Selfie');
|
|
69
|
+
|
|
70
|
+
cy.get('smart-camera-web')
|
|
71
|
+
.shadow()
|
|
72
|
+
.find('selfie-capture')
|
|
73
|
+
.shadow()
|
|
74
|
+
.find('#start-image-capture')
|
|
75
|
+
.click();
|
|
76
|
+
|
|
77
|
+
cy.tick(8000);
|
|
78
|
+
|
|
79
|
+
cy.get('smart-camera-web')
|
|
80
|
+
.shadow()
|
|
81
|
+
.find('selfie-capture')
|
|
82
|
+
.shadow()
|
|
83
|
+
.should('not.be.visible');
|
|
84
|
+
|
|
85
|
+
cy.get('smart-camera-web')
|
|
86
|
+
.shadow()
|
|
87
|
+
.find('selfie-capture-review')
|
|
88
|
+
.should('be.visible');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should not show the agent mode switch button"', () => {
|
|
92
|
+
cy.get('smart-camera-web')
|
|
93
|
+
.shadow()
|
|
94
|
+
.find('selfie-capture')
|
|
95
|
+
.invoke('attr', 'show-agent-mode-for-tests', 'false');
|
|
96
|
+
cy.get('smart-camera-web').invoke('attr', 'disable-image-tests', '');
|
|
97
|
+
|
|
98
|
+
cy.clock();
|
|
99
|
+
cy.get('smart-camera-web')
|
|
100
|
+
.shadow()
|
|
101
|
+
.find('selfie-capture-instructions')
|
|
102
|
+
.shadow()
|
|
103
|
+
.find('#allow')
|
|
104
|
+
.click();
|
|
105
|
+
|
|
106
|
+
cy.get('smart-camera-web')
|
|
107
|
+
.shadow()
|
|
108
|
+
.find('selfie-capture')
|
|
109
|
+
.should('be.visible');
|
|
110
|
+
|
|
111
|
+
cy.get('smart-camera-web')
|
|
112
|
+
.shadow()
|
|
113
|
+
.find('selfie-capture')
|
|
114
|
+
.shadow()
|
|
115
|
+
.find('#switch-camera')
|
|
116
|
+
.should('not.exist');
|
|
117
|
+
|
|
118
|
+
cy.get('smart-camera-web')
|
|
119
|
+
.shadow()
|
|
120
|
+
.find('selfie-capture')
|
|
121
|
+
.shadow()
|
|
122
|
+
.should('contain.text', 'Take a Selfie');
|
|
123
|
+
|
|
124
|
+
cy.get('smart-camera-web')
|
|
125
|
+
.shadow()
|
|
126
|
+
.find('selfie-capture')
|
|
127
|
+
.shadow()
|
|
128
|
+
.find('#start-image-capture')
|
|
129
|
+
.click();
|
|
130
|
+
|
|
131
|
+
cy.tick(8000);
|
|
132
|
+
|
|
133
|
+
cy.get('smart-camera-web')
|
|
134
|
+
.shadow()
|
|
135
|
+
.find('selfie-capture')
|
|
136
|
+
.shadow()
|
|
137
|
+
.should('not.be.visible');
|
|
138
|
+
|
|
139
|
+
cy.get('smart-camera-web')
|
|
140
|
+
.shadow()
|
|
141
|
+
.find('selfie-capture-review')
|
|
142
|
+
.should('be.visible');
|
|
143
|
+
});
|
|
144
|
+
});
|