@descope-ui/descope-address-field 0.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## 0.0.1 (2025-02-17)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `e2e-utils` updated to version `0.0.1`
10
+ * `test-drivers` updated to version `0.0.1`
11
+ * `@descope-ui/common` updated to version `0.0.4`
12
+ * `@descope-ui/theme-input-wrapper` updated to version `0.0.4`
13
+ * `@descope-ui/descope-autocomplete-field` updated to version `0.0.2`
@@ -0,0 +1,190 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import { getStoryUrl } from 'e2e-utils';
3
+ import createAddressFieldTestDriver from '../testDriver/addressFieldTestDriver';
4
+ import { MOCK_SUGGESTIONS, MOCK_SUGGESTIONS_SINGLE } from './mocks';
5
+ const storyName = 'descope-address-field';
6
+ const componentName = 'descope-address-field';
7
+
8
+ declare global {
9
+ interface Window {
10
+ google: any;
11
+ __lastRequest: any;
12
+ }
13
+ }
14
+
15
+ const googleMapsAttrs = {
16
+ 'allow-custom-value': 'false',
17
+ 'connector-template': 'google-maps-places',
18
+ 'public-api-key': 'test-api-key',
19
+ };
20
+
21
+ test.describe('connectors - google', () => {
22
+ test('no api key', async ({ page }) => {
23
+ await page.route('**/*apis.com/maps/api/js*', (route) => {
24
+ throw new Error(
25
+ 'Google Maps script should not be loaded when no API key is provided',
26
+ );
27
+ });
28
+
29
+ await page.goto(
30
+ getStoryUrl(storyName, {
31
+ 'allow-custom-value': 'false',
32
+ 'connector-template': 'google-maps-places',
33
+ }),
34
+ );
35
+ const locator = page.locator(componentName);
36
+ const component = createAddressFieldTestDriver(locator);
37
+ await component.insertValue('fastmock');
38
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
39
+ hasText: 'An error occurred',
40
+ });
41
+ await resultsLoaded.waitFor();
42
+ await expect(component.dropDown).toBeVisible();
43
+ const item = page.locator(componentName).getByRole('option').first();
44
+ await expect(item).toHaveAttribute('disabled', 'true');
45
+ await expect(item).toHaveText('An error occurred fetching results');
46
+ });
47
+
48
+ test('load google maps script with api key', async ({ page }) => {
49
+ let googleScriptLoaded = false;
50
+
51
+ await page.route('**/*apis.com/maps/api/js*', (route) => {
52
+ googleScriptLoaded = true;
53
+ });
54
+
55
+ await page.goto(getStoryUrl(storyName, googleMapsAttrs));
56
+ // Verify Google Maps script was loaded
57
+ await expect(async () => {
58
+ expect(googleScriptLoaded).toBe(true);
59
+ }).toPass();
60
+ });
61
+
62
+ test('with api key', async ({ page }) => {
63
+ await page.addInitScript((mockSuggestions) => {
64
+ window.__lastRequest = null;
65
+ window.google = {
66
+ maps: {
67
+ importLibrary: () =>
68
+ Promise.resolve({
69
+ AutocompleteSuggestion: class {
70
+ static async fetchAutocompleteSuggestions(req) {
71
+ window.__lastRequest = req;
72
+ // Simulate network delay
73
+ await new Promise((resolve) => setTimeout(resolve, 100));
74
+ return mockSuggestions;
75
+ }
76
+ },
77
+ }),
78
+ },
79
+ };
80
+ }, MOCK_SUGGESTIONS);
81
+
82
+ await page.goto(getStoryUrl(storyName, googleMapsAttrs));
83
+ const locator = page.locator(componentName);
84
+ const component = createAddressFieldTestDriver(locator);
85
+ await component.insertValue('mock');
86
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
87
+ hasText: 'Mock Street',
88
+ });
89
+ await resultsLoaded.waitFor();
90
+ const items = await component.getItems();
91
+ expect(items.length).toEqual(3);
92
+ await expect(component.dropDown).toBeVisible();
93
+ await component.selectItem('123 Mock Street');
94
+ expect(await component.getValue()).toBe(
95
+ '123 Mock Street, Mock City, MC 12345',
96
+ );
97
+ await expect(component.dropDown).not.toBeVisible();
98
+ const request = await page.evaluate(() => window.__lastRequest);
99
+ await expect(request).toEqual({
100
+ input: 'mock',
101
+ });
102
+ expect(await component.screenshot()).toMatchSnapshot();
103
+ });
104
+
105
+ test('with optional parameters', async ({ page }) => {
106
+ await page.addInitScript((mockSuggestions) => {
107
+ window.__lastRequest = null;
108
+ window.google = {
109
+ maps: {
110
+ importLibrary: () =>
111
+ Promise.resolve({
112
+ AutocompleteSuggestion: class {
113
+ static async fetchAutocompleteSuggestions(req) {
114
+ window.__lastRequest = req;
115
+ // Simulate network delay
116
+ await new Promise((resolve) => setTimeout(resolve, 100));
117
+ return mockSuggestions;
118
+ }
119
+ },
120
+ }),
121
+ },
122
+ };
123
+ }, MOCK_SUGGESTIONS_SINGLE);
124
+
125
+ await page.goto(
126
+ getStoryUrl(storyName, {
127
+ ...googleMapsAttrs,
128
+ 'address-language': 'en-US',
129
+ 'address-region': 'us',
130
+ }),
131
+ );
132
+ const locator = page.locator(componentName);
133
+ const component = createAddressFieldTestDriver(locator);
134
+ // This attribute needs to be added to the HTML since storybook does not support adding "," in the attribute value
135
+ await locator.evaluate((el) => {
136
+ el.setAttribute('address-types', 'street_address, finance');
137
+ });
138
+ await component.insertValue('mock');
139
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
140
+ hasText: 'Mock Street',
141
+ });
142
+ await resultsLoaded.waitFor();
143
+ const items = await component.getItems();
144
+ expect(items.length).toBeGreaterThan(0);
145
+ await expect(component.dropDown).toBeVisible();
146
+ await component.selectItem('123 Mock Street');
147
+ expect(await component.getValue()).toBe(
148
+ '123 Mock Street, Mock City, MC 12345',
149
+ );
150
+ await expect(component.dropDown).not.toBeVisible();
151
+ const request = await page.evaluate(() => window.__lastRequest);
152
+ await expect(request).toEqual({
153
+ input: 'mock',
154
+ includedPrimaryTypes: ['street_address', 'finance'],
155
+ language: 'en-US',
156
+ region: 'us',
157
+ });
158
+ });
159
+
160
+ test('handles API error', async ({ page }) => {
161
+ await page.addInitScript(() => {
162
+ window.google = {
163
+ maps: {
164
+ importLibrary: () =>
165
+ Promise.resolve({
166
+ AutocompleteSuggestion: class {
167
+ static async fetchAutocompleteSuggestions(req) {
168
+ await new Promise((resolve) => setTimeout(resolve, 100));
169
+ throw new Error('API error');
170
+ }
171
+ },
172
+ }),
173
+ },
174
+ };
175
+ });
176
+
177
+ await page.goto(getStoryUrl(storyName, googleMapsAttrs));
178
+ const locator = page.locator(componentName);
179
+ const component = createAddressFieldTestDriver(locator);
180
+ await component.insertValue('fastmock');
181
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
182
+ hasText: 'An error occurred',
183
+ });
184
+ await resultsLoaded.waitFor();
185
+ await expect(component.dropDown).toBeVisible();
186
+ const item = page.locator(componentName).getByRole('option').first();
187
+ await expect(item).toHaveAttribute('disabled', 'true');
188
+ await expect(item).toHaveText('An error occurred fetching results');
189
+ });
190
+ });
@@ -0,0 +1,167 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import { getStoryUrl } from 'e2e-utils';
3
+ import createAddressFieldTestDriver from '../testDriver/addressFieldTestDriver';
4
+
5
+ const storyName = 'descope-address-field';
6
+ const componentName = 'descope-address-field';
7
+
8
+ const radarAttrs = {
9
+ 'allow-custom-value': 'false',
10
+ 'connector-template': 'radar',
11
+ 'public-api-key': 'test-api-key',
12
+ };
13
+
14
+ const MOCK_RADAR_AUTOCOMPLETE_SUGGESTIONS = {
15
+ addresses: [
16
+ { formattedAddress: '123 Mock Street, Mock City, MC 12345' },
17
+ { formattedAddress: '456 Test Avenue, Mock Town, TT 67890' },
18
+ { formattedAddress: '789 Sample Boulevard, Mock City, DC 54321' },
19
+ ],
20
+ };
21
+
22
+ const MOCK_RADAR_AUTOCOMPLETE_SUGGESTIONS_2 = {
23
+ addresses: [
24
+ { formattedAddress: '123 Mock Street, Mock City, MC 12345' },
25
+ { formattedAddress: '456 Test Avenue, Mock Town, TT 67890' },
26
+ ],
27
+ };
28
+
29
+ test.describe('connectors - radar', () => {
30
+ test('no api key', async ({ page }) => {
31
+ await page.goto(
32
+ getStoryUrl(storyName, {
33
+ 'allow-custom-value': 'false',
34
+ 'connector-template': 'radar',
35
+ }),
36
+ );
37
+ const locator = page.locator(componentName);
38
+ const component = createAddressFieldTestDriver(locator);
39
+ await component.insertValue('fastmock');
40
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
41
+ hasText: 'An error occurred',
42
+ });
43
+ await resultsLoaded.waitFor();
44
+ await expect(component.dropDown).toBeVisible();
45
+ const item = page.locator(componentName).getByRole('option').first();
46
+ await expect(item).toHaveAttribute('disabled', 'true');
47
+ await expect(item).toHaveText('An error occurred fetching results');
48
+ });
49
+
50
+ test('with api key', async ({ page }) => {
51
+ await page.goto(getStoryUrl(storyName, radarAttrs));
52
+
53
+ await page.route(
54
+ '**/*api.radar.io/v1/search/autocomplete*',
55
+ async (route) => {
56
+ const req = route.request();
57
+ const url = new URL(req.url());
58
+ const headers = req.headers();
59
+ // Assert headers
60
+ expect(headers['authorization']).toBe('test-api-key');
61
+ // Assert URL parameters
62
+ expect(url.searchParams.size).toBe(1);
63
+ expect(url.searchParams.get('query')).toBe('mock');
64
+ route.fulfill({
65
+ status: 200,
66
+ body: JSON.stringify(MOCK_RADAR_AUTOCOMPLETE_SUGGESTIONS),
67
+ });
68
+ },
69
+ );
70
+
71
+ const locator = page.locator(componentName);
72
+ const component = createAddressFieldTestDriver(locator);
73
+ await component.insertValue('mock');
74
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
75
+ hasText: 'Mock Street',
76
+ });
77
+ await resultsLoaded.waitFor();
78
+ const items = await component.getItems();
79
+ expect(items.length).toEqual(3);
80
+ await expect(component.dropDown).toBeVisible();
81
+ await component.selectItem('123 Mock Street');
82
+ expect(await component.getValue()).toBe(
83
+ '123 Mock Street, Mock City, MC 12345',
84
+ );
85
+ await expect(component.dropDown).not.toBeVisible();
86
+ expect(await component.screenshot()).toMatchSnapshot();
87
+ });
88
+
89
+ test('with optional parameters', async ({ page }) => {
90
+ await page.goto(
91
+ getStoryUrl(storyName, {
92
+ ...radarAttrs,
93
+ 'address-language': 'en',
94
+ 'address-limit': '5',
95
+ }),
96
+ );
97
+ const locator = page.locator(componentName);
98
+ const component = createAddressFieldTestDriver(locator);
99
+
100
+ // These attributes need to be added to the HTML since storybook does not support adding "," in the attribute value
101
+ await locator.evaluate((el) => {
102
+ el.setAttribute('address-types', 'address, state');
103
+ el.setAttribute('address-region', 'US,AR');
104
+ });
105
+
106
+ await page.route(
107
+ '**/*api.radar.io/v1/search/autocomplete*',
108
+ async (route) => {
109
+ const req = route.request();
110
+ const url = new URL(req.url());
111
+ const headers = req.headers();
112
+ // Assert headers
113
+ expect(headers['authorization']).toBe('test-api-key');
114
+ // Assert URL parameters
115
+ expect(url.searchParams.size).toBe(5);
116
+ expect(url.searchParams.get('query')).toBe('mock');
117
+ expect(url.searchParams.get('lang')).toBe('en');
118
+ expect(url.searchParams.get('countryCode')).toBe('US,AR');
119
+ expect(url.searchParams.get('limit')).toBe('5');
120
+ expect(url.searchParams.get('layers')).toBe('address,state');
121
+ route.fulfill({
122
+ status: 200,
123
+ body: JSON.stringify(MOCK_RADAR_AUTOCOMPLETE_SUGGESTIONS_2),
124
+ });
125
+ },
126
+ );
127
+
128
+ await component.insertValue('mock');
129
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
130
+ hasText: 'Mock Street',
131
+ });
132
+ await resultsLoaded.waitFor();
133
+ const items = await component.getItems();
134
+ expect(items.length).toEqual(2);
135
+ await expect(component.dropDown).toBeVisible();
136
+ await component.selectItem('123 Mock Street');
137
+ expect(await component.getValue()).toBe(
138
+ '123 Mock Street, Mock City, MC 12345',
139
+ );
140
+ await expect(component.dropDown).not.toBeVisible();
141
+ });
142
+
143
+ test('handles API error', async ({ page }) => {
144
+ await page.goto(getStoryUrl(storyName, radarAttrs));
145
+
146
+ await page.route(
147
+ '**/*api.radar.io/v1/search/autocomplete*',
148
+ async (route) => {
149
+ route.fulfill({
150
+ status: 400,
151
+ body: 'Bad Request',
152
+ });
153
+ },
154
+ );
155
+
156
+ const locator = page.locator(componentName);
157
+ const component = createAddressFieldTestDriver(locator);
158
+ await component.insertValue('mock');
159
+ const resultsLoaded = page.locator('vaadin-combo-box-item', {
160
+ hasText: 'An error occurred',
161
+ });
162
+ await resultsLoaded.waitFor();
163
+ const item = page.locator(componentName).getByRole('option').first();
164
+ await expect(item).toHaveAttribute('disabled', 'true');
165
+ await expect(item).toHaveText('An error occurred fetching results');
166
+ });
167
+ });