@controleonline/ui-customers 1.0.81
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/.github/agents/developer.agent.md +30 -0
- package/.github/agents/devops.agent.md +30 -0
- package/.github/agents/qa.agent.md +30 -0
- package/.github/agents/security.agent.md +30 -0
- package/.scrutinizer.yml +20 -0
- package/AGENTS.md +50 -0
- package/FUNDING.yml +1 -0
- package/README.md +23 -0
- package/docs/technical/Client-Details-Franquia-Filial.md +18 -0
- package/docs/technical/Client-Details-People-Name-Case.md +103 -0
- package/docs/technical/Cliente-Vendedor-Vinculo-e-Permissoes.md +152 -0
- package/docs/wiki.md +1 -0
- package/package.json +32 -0
- package/scripts/validate-wiki-pointer.cjs +13 -0
- package/src/react/components/tabs/AddressesTab.js +494 -0
- package/src/react/components/tabs/CategoriesTab.js +196 -0
- package/src/react/components/tabs/ClassificationChips.js +494 -0
- package/src/react/components/tabs/ContactTab.js +621 -0
- package/src/react/components/tabs/ContactTab.styles.js +119 -0
- package/src/react/components/tabs/ContractsTab.js +13 -0
- package/src/react/components/tabs/DocumentsTab.js +463 -0
- package/src/react/components/tabs/DocumentsTab.styles.js +133 -0
- package/src/react/components/tabs/EmployeeContactRow.js +83 -0
- package/src/react/components/tabs/EmployeesTab.js +454 -0
- package/src/react/components/tabs/EmployeesTab.styles.js +172 -0
- package/src/react/components/tabs/FiscalTab.js +6 -0
- package/src/react/components/tabs/FranchiseCommissionSection.js +307 -0
- package/src/react/components/tabs/FranchiseLinksManageModal.js +215 -0
- package/src/react/components/tabs/FranchiseLinksTab.js +282 -0
- package/src/react/components/tabs/GeneralTab.js +466 -0
- package/src/react/components/tabs/GeneralTab.styles.js +101 -0
- package/src/react/components/tabs/MediaTab.js +356 -0
- package/src/react/components/tabs/PeopleCategoriesPanel.js +601 -0
- package/src/react/components/tabs/ProductsTab.js +236 -0
- package/src/react/components/tabs/ProductsTab.styles.js +143 -0
- package/src/react/components/tabs/SalesmanCommissionBlock.js +120 -0
- package/src/react/components/tabs/SalesmanManageModal.js +208 -0
- package/src/react/components/tabs/SalesmanTab.js +436 -0
- package/src/react/components/tabs/SalesmanTab.styles.js +4 -0
- package/src/react/components/tabs/UserApiKeyModal.js +90 -0
- package/src/react/components/tabs/UserFormModal.js +301 -0
- package/src/react/components/tabs/UsersTab.js +426 -0
- package/src/react/components/tabs/UsersTab.styles.js +283 -0
- package/src/react/components/tabs/UsersTab.styles.test.js +42 -0
- package/src/react/components/tabs/contactMutationMessage.js +18 -0
- package/src/react/components/tabs/employeeContacts.js +214 -0
- package/src/react/components/tabs/employeeUnlink.js +68 -0
- package/src/react/components/tabs/employeesTabHelpers.js +227 -0
- package/src/react/components/tabs/franchiseCommissionHelpers.js +134 -0
- package/src/react/components/tabs/franchiseLinksTab.helpers.js +247 -0
- package/src/react/components/tabs/generalTabHelpers.js +120 -0
- package/src/react/components/tabs/salesmanTab.helpers.js +114 -0
- package/src/react/components/tabs/salesmanTabHelpers.js +173 -0
- package/src/react/components/tabs/salesmanTabMedia.js +55 -0
- package/src/react/components/tabs/salesmanTabSession.js +39 -0
- package/src/react/components/tabs/useEmployeeUnlink.js +58 -0
- package/src/react/components/tabs/useFranchiseLinksManage.js +215 -0
- package/src/react/components/tabs/useSalesmanManage.js +222 -0
- package/src/react/components/tabs/usersTabHelpers.js +221 -0
- package/src/react/domain/productSupplierFlow.js +37 -0
- package/src/react/index.js +4 -0
- package/src/react/pages/ClientDetailsSkeleton.js +84 -0
- package/src/react/pages/clientDetailsHelpers.js +17 -0
- package/src/react/pages/clients.js +27 -0
- package/src/react/pages/details.js +529 -0
- package/src/react/pages/details.page.styles.js +105 -0
- package/src/react/pages/details.styles.js +15 -0
- package/src/react/pages/employees.js +69 -0
- package/src/react/pages/franchisees.js +30 -0
- package/src/react/pages/prospects.js +21 -0
- package/src/react/pages/provider.js +21 -0
- package/src/react/router/routes.js +104 -0
- package/src/react/styles/details.js +571 -0
- package/src/store/people_categories/index.js +72 -0
- package/src/tests/browser/manager/client-details-create-user.spec.js +321 -0
- package/src/tests/browser/manager/client-details-employee-unlink.spec.js +215 -0
- package/src/tests/browser/manager/client-details-employees-refresh.spec.js +271 -0
- package/src/tests/browser/manager/client-details-enable.spec.js +241 -0
- package/src/tests/browser/manager/client-details-fiscal-tabs.spec.js +410 -0
- package/src/tests/browser/manager/client-details-franchise-commission.spec.js +318 -0
- package/src/tests/browser/manager/client-details-franchise-links.spec.js +365 -0
- package/src/tests/browser/manager/client-details-media.spec.js +405 -0
- package/src/tests/browser/manager/client-details-relationships.spec.js +313 -0
- package/src/tests/browser/manager/client-details-salesman-commission.spec.js +291 -0
- package/src/tests/browser/manager/client-details-salesman-manage.spec.js +448 -0
- package/src/tests/react/components/tabs/contactMutationMessage.test.js +25 -0
- package/src/tests/react/components/tabs/employeeContacts.test.js +266 -0
- package/src/tests/react/components/tabs/employeeUnlink.test.js +67 -0
- package/src/tests/react/components/tabs/employeesTabHelpers.media.test.js +78 -0
- package/src/tests/react/components/tabs/employeesTabHelpers.test.js +64 -0
- package/src/tests/react/components/tabs/fiscalTabContract.test.mjs +29 -0
- package/src/tests/react/components/tabs/franchiseCommissionHelpers.test.js +128 -0
- package/src/tests/react/components/tabs/franchiseLinksTab.helpers.test.mjs +166 -0
- package/src/tests/react/components/tabs/generalTabHelpers.test.js +130 -0
- package/src/tests/react/components/tabs/peopleMediaTabs.test.js +322 -0
- package/src/tests/react/components/tabs/salesmanTab.helpers.test.mjs +75 -0
- package/src/tests/react/components/tabs/salesmanTabHelpers.test.js +142 -0
- package/src/tests/react/components/tabs/salesmanTabHelpers.test.mjs +92 -0
- package/src/tests/react/components/tabs/usersTabHelpers.test.js +59 -0
- package/src/tests/react/domain/productSupplierFlow.test.mjs +55 -0
- package/src/tests/react/pages/clientDetailsHelpers.test.js +98 -0
- package/src/tests/react/pages/employees.test.js +44 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fluxo: outros
|
|
3
|
+
* flowchartIds: [1]
|
|
4
|
+
* app-community#682 — fiscal tabs load once, no marketplace Provider toast, values persist across sub-tabs.
|
|
5
|
+
*
|
|
6
|
+
* Justificativa fluxo outros: configuração fiscal de empresa (Receita Federal) não é jornada
|
|
7
|
+
* de venda/produção/POS; usa flowchartIds [1] só como âncora admin habilitada.
|
|
8
|
+
*/
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const {expect, test} = require('playwright/test');
|
|
12
|
+
const {API_ORIGIN} = require('../../../../../../../src/tests/browser/apiOrigin');
|
|
13
|
+
const {version: appVersion} = require('../../../../../../../package.json');
|
|
14
|
+
|
|
15
|
+
const FLOW_ID = 'outros';
|
|
16
|
+
const FLOWCHART_IDS = [1];
|
|
17
|
+
const FLOWCHART_LINKS = FLOWCHART_IDS.map(
|
|
18
|
+
id => `https://admin.controleonline.com/admin/flowcharts/${id}`,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const evidenceSteps = [];
|
|
22
|
+
|
|
23
|
+
const writeEvidence = async (page, outputDir, stepId, title) => {
|
|
24
|
+
fs.mkdirSync(outputDir, {recursive: true});
|
|
25
|
+
const fileName = `${stepId}.png`;
|
|
26
|
+
const filePath = path.join(outputDir, fileName);
|
|
27
|
+
await page.screenshot({path: filePath, fullPage: true});
|
|
28
|
+
evidenceSteps.push({
|
|
29
|
+
id: stepId,
|
|
30
|
+
title,
|
|
31
|
+
screenshot: fileName,
|
|
32
|
+
url: page.url(),
|
|
33
|
+
});
|
|
34
|
+
return filePath;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const writeManifest = outputDir => {
|
|
38
|
+
const manifest = {
|
|
39
|
+
fluxo: FLOW_ID,
|
|
40
|
+
flowchartIds: FLOWCHART_IDS,
|
|
41
|
+
flowchartLinks: FLOWCHART_LINKS,
|
|
42
|
+
title:
|
|
43
|
+
'my-company-details fiscal tabs: load once, no Provider toast, values persist',
|
|
44
|
+
issue: 'ControleOnline/app-community#682',
|
|
45
|
+
steps: evidenceSteps,
|
|
46
|
+
};
|
|
47
|
+
fs.writeFileSync(
|
|
48
|
+
path.join(outputDir, 'manifest.json'),
|
|
49
|
+
`${JSON.stringify(manifest, null, 2)}\n`,
|
|
50
|
+
);
|
|
51
|
+
return manifest;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const CORS_HEADERS = {
|
|
55
|
+
'access-control-allow-origin': '*',
|
|
56
|
+
'access-control-allow-headers':
|
|
57
|
+
'API-TOKEN, APP-DOMAIN, DEVICE, ACCEPT, CONTENT-TYPE, X-Requested-With',
|
|
58
|
+
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const collection = (member = [], summary = {}) => ({
|
|
62
|
+
member,
|
|
63
|
+
'hydra:member': member,
|
|
64
|
+
totalItems: member.length,
|
|
65
|
+
'hydra:totalItems': member.length,
|
|
66
|
+
summary,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const jsonHeaders = () => ({
|
|
70
|
+
...CORS_HEADERS,
|
|
71
|
+
'content-type': 'application/ld+json; charset=utf-8',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const textHeaders = () => ({
|
|
75
|
+
...CORS_HEADERS,
|
|
76
|
+
'content-type': 'text/css; charset=utf-8',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const COMPANY_ID = 2;
|
|
80
|
+
const COMPANY = {
|
|
81
|
+
'@id': `/people/${COMPANY_ID}`,
|
|
82
|
+
id: COMPANY_ID,
|
|
83
|
+
name: 'EMPRESA FISCAL TESTE LTDA',
|
|
84
|
+
alias: 'EMPRESA FISCAL',
|
|
85
|
+
peopleType: 'J',
|
|
86
|
+
enable: true,
|
|
87
|
+
panel_enabled: true,
|
|
88
|
+
enabled: true,
|
|
89
|
+
commercial_enabled: true,
|
|
90
|
+
theme: {
|
|
91
|
+
colors: {
|
|
92
|
+
primary: '#166534',
|
|
93
|
+
secondary: '#D9A441',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const FISCAL_CONFIGS = [
|
|
99
|
+
{
|
|
100
|
+
'@id': '/configs/1',
|
|
101
|
+
id: 1,
|
|
102
|
+
people: `/people/${COMPANY_ID}`,
|
|
103
|
+
configKey: 'receita-federal-tax-regime',
|
|
104
|
+
configValue: '1',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
'@id': '/configs/2',
|
|
108
|
+
id: 2,
|
|
109
|
+
people: `/people/${COMPANY_ID}`,
|
|
110
|
+
configKey: 'receita-federal-ibge-code',
|
|
111
|
+
configValue: '3550308',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
'@id': '/configs/3',
|
|
115
|
+
id: 3,
|
|
116
|
+
people: `/people/${COMPANY_ID}`,
|
|
117
|
+
configKey: 'receita-federal-environment',
|
|
118
|
+
configValue: '2',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
'@id': '/configs/4',
|
|
122
|
+
id: 4,
|
|
123
|
+
people: `/people/${COMPANY_ID}`,
|
|
124
|
+
configKey: 'receita-federal-nfe-enabled',
|
|
125
|
+
configValue: '1',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
'@id': '/configs/5',
|
|
129
|
+
id: 5,
|
|
130
|
+
people: `/people/${COMPANY_ID}`,
|
|
131
|
+
configKey: 'receita-federal-nfe-serie',
|
|
132
|
+
configValue: '1',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
'@id': '/configs/6',
|
|
136
|
+
id: 6,
|
|
137
|
+
people: `/people/${COMPANY_ID}`,
|
|
138
|
+
configKey: 'receita-federal-nfce-enabled',
|
|
139
|
+
configValue: '1',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
'@id': '/configs/7',
|
|
143
|
+
id: 7,
|
|
144
|
+
people: `/people/${COMPANY_ID}`,
|
|
145
|
+
configKey: 'receita-federal-nfce-serie',
|
|
146
|
+
configValue: '1',
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
const mockFiscalCompanyApi = async page => {
|
|
151
|
+
const marketplaceHits = [];
|
|
152
|
+
const configsHits = [];
|
|
153
|
+
const pageErrors = [];
|
|
154
|
+
|
|
155
|
+
page.on('pageerror', error => {
|
|
156
|
+
pageErrors.push(String(error?.message || error));
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
await page.route(`${API_ORIGIN}/**`, async route => {
|
|
160
|
+
const request = route.request();
|
|
161
|
+
const url = new URL(request.url());
|
|
162
|
+
const pathname = url.pathname.replace(/^\/+/, '');
|
|
163
|
+
const method = request.method().toUpperCase();
|
|
164
|
+
|
|
165
|
+
if (method === 'OPTIONS') {
|
|
166
|
+
return route.fulfill({status: 204, headers: CORS_HEADERS, body: ''});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (pathname === 'themes-colors.css') {
|
|
170
|
+
return route.fulfill({
|
|
171
|
+
status: 200,
|
|
172
|
+
headers: textHeaders(),
|
|
173
|
+
body: ':root { --primary: #166534; --secondary: #d9a441; }',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (pathname === 'runtime/ip') {
|
|
178
|
+
return route.fulfill({
|
|
179
|
+
status: 200,
|
|
180
|
+
headers: jsonHeaders(),
|
|
181
|
+
body: JSON.stringify({ip: '127.0.0.1'}),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (pathname === 'company/default' || pathname === 'people/companies/my') {
|
|
186
|
+
return route.fulfill({
|
|
187
|
+
status: 200,
|
|
188
|
+
headers: jsonHeaders(),
|
|
189
|
+
body: JSON.stringify(
|
|
190
|
+
pathname === 'company/default' ? COMPANY : collection([COMPANY]),
|
|
191
|
+
),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (pathname === `people/${COMPANY_ID}`) {
|
|
196
|
+
return route.fulfill({
|
|
197
|
+
status: 200,
|
|
198
|
+
headers: jsonHeaders(),
|
|
199
|
+
body: JSON.stringify(COMPANY),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (pathname === 'configs' || pathname.startsWith('configs')) {
|
|
204
|
+
configsHits.push({method, search: url.search});
|
|
205
|
+
return route.fulfill({
|
|
206
|
+
status: 200,
|
|
207
|
+
headers: jsonHeaders(),
|
|
208
|
+
body: JSON.stringify(collection(FISCAL_CONFIGS)),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (pathname.startsWith('marketplace/integrations')) {
|
|
213
|
+
marketplaceHits.push({
|
|
214
|
+
method,
|
|
215
|
+
search: url.search,
|
|
216
|
+
provider_id: url.searchParams.get('provider_id'),
|
|
217
|
+
});
|
|
218
|
+
// Simulate the prod failure the bug reported — pure fiscal must never hit this.
|
|
219
|
+
return route.fulfill({
|
|
220
|
+
status: 404,
|
|
221
|
+
headers: jsonHeaders(),
|
|
222
|
+
body: JSON.stringify({
|
|
223
|
+
code: -1,
|
|
224
|
+
detail: 'Provider not found or access denied',
|
|
225
|
+
}),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (pathname === 'menus-people') {
|
|
230
|
+
return route.fulfill({
|
|
231
|
+
status: 200,
|
|
232
|
+
headers: jsonHeaders(),
|
|
233
|
+
body: JSON.stringify({modules: {}}),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (pathname === 'configs/discovery-configs') {
|
|
238
|
+
return route.fulfill({
|
|
239
|
+
status: 200,
|
|
240
|
+
headers: jsonHeaders(),
|
|
241
|
+
body: JSON.stringify({configs: {}}),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (pathname === 'people_links' || pathname.startsWith('people_links')) {
|
|
246
|
+
return route.fulfill({
|
|
247
|
+
status: 200,
|
|
248
|
+
headers: jsonHeaders(),
|
|
249
|
+
body: JSON.stringify(collection([])),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (pathname === 'statuses' || pathname.startsWith('statuses')) {
|
|
254
|
+
return route.fulfill({
|
|
255
|
+
status: 200,
|
|
256
|
+
headers: jsonHeaders(),
|
|
257
|
+
body: JSON.stringify(collection([])),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return route.fulfill({
|
|
262
|
+
status: 200,
|
|
263
|
+
headers: jsonHeaders(),
|
|
264
|
+
body: JSON.stringify(collection([])),
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
await page.addInitScript(
|
|
269
|
+
({appVersion, companyId}) => {
|
|
270
|
+
const setLocalStorageItem = (key, value) => {
|
|
271
|
+
try {
|
|
272
|
+
localStorage.setItem(key, value);
|
|
273
|
+
} catch {
|
|
274
|
+
// ignore
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
setLocalStorageItem(
|
|
279
|
+
'session',
|
|
280
|
+
JSON.stringify({
|
|
281
|
+
id: 7,
|
|
282
|
+
people: '/people/7',
|
|
283
|
+
api_key: 'test-api-key',
|
|
284
|
+
active: 1,
|
|
285
|
+
mycompany: companyId,
|
|
286
|
+
roles: ['ROLE_SUPER', 'ROLE_ADMIN'],
|
|
287
|
+
}),
|
|
288
|
+
);
|
|
289
|
+
setLocalStorageItem('config', JSON.stringify({language: 'pt-br'}));
|
|
290
|
+
setLocalStorageItem('app-type', 'MANAGER');
|
|
291
|
+
setLocalStorageItem(
|
|
292
|
+
'device',
|
|
293
|
+
JSON.stringify({
|
|
294
|
+
id: 'web-manager',
|
|
295
|
+
device: 'web-manager',
|
|
296
|
+
type: 'WEB',
|
|
297
|
+
appName: 'Browser Manager',
|
|
298
|
+
appVersion,
|
|
299
|
+
buildNumber: appVersion,
|
|
300
|
+
systemName: 'web',
|
|
301
|
+
systemVersion: 'web',
|
|
302
|
+
deviceType: 'web',
|
|
303
|
+
metadata: {},
|
|
304
|
+
}),
|
|
305
|
+
);
|
|
306
|
+
},
|
|
307
|
+
{appVersion, companyId: COMPANY_ID},
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
getMarketplaceHits: () => marketplaceHits,
|
|
312
|
+
getConfigsHits: () => configsHits,
|
|
313
|
+
getPageErrors: () => pageErrors,
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
test.describe('client details fiscal tabs browser smoke (#682)', () => {
|
|
318
|
+
test('fiscal sub-tabs load once, skip marketplace, keep values visible', async ({
|
|
319
|
+
page,
|
|
320
|
+
}) => {
|
|
321
|
+
const outputDir = path.join(
|
|
322
|
+
process.cwd(),
|
|
323
|
+
'test-results',
|
|
324
|
+
'client-details-fiscal-tabs',
|
|
325
|
+
);
|
|
326
|
+
evidenceSteps.length = 0;
|
|
327
|
+
|
|
328
|
+
const api = await mockFiscalCompanyApi(page);
|
|
329
|
+
|
|
330
|
+
await page.goto(
|
|
331
|
+
`/my-company-details?clientId=${COMPANY_ID}&contextKey=company`,
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
await expect(
|
|
335
|
+
page.getByText(/EMPRESA FISCAL|Configurações Fiscais|Dados Cadastrais/i).first(),
|
|
336
|
+
).toBeVisible({timeout: 20000});
|
|
337
|
+
|
|
338
|
+
await writeEvidence(page, outputDir, '01-company-details', 'Company details loaded');
|
|
339
|
+
|
|
340
|
+
// Open Fiscal tab (label from helpers: Configurações Fiscais)
|
|
341
|
+
const fiscalTab = page.getByText(/Configurações Fiscais|Configuracoes Fiscais|Fiscal/i).first();
|
|
342
|
+
await expect(fiscalTab).toBeVisible({timeout: 15000});
|
|
343
|
+
await fiscalTab.click();
|
|
344
|
+
|
|
345
|
+
// Gerais is the default sub-tab
|
|
346
|
+
await expect(page.getByText(/Gerais/i).first()).toBeVisible({timeout: 15000});
|
|
347
|
+
await expect(page.getByText(/Regime tributario|Regime tributário/i).first()).toBeVisible({
|
|
348
|
+
timeout: 10000,
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
await writeEvidence(page, outputDir, '02-fiscal-gerais', 'Fiscal tab Gerais visible');
|
|
352
|
+
|
|
353
|
+
const configsAfterOpen = api.getConfigsHits().length;
|
|
354
|
+
|
|
355
|
+
// Switch to NF-e
|
|
356
|
+
await page.getByText(/NF-e \(produtos\)|NF-e/i).first().click();
|
|
357
|
+
await expect(page.getByText(/Habilitar NF-e/i).first()).toBeVisible({timeout: 10000});
|
|
358
|
+
await expect(page.getByText(/Serie NF-e|Série NF-e/i).first()).toBeVisible({
|
|
359
|
+
timeout: 5000,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
await writeEvidence(page, outputDir, '03-fiscal-nfe', 'Fiscal tab NF-e visible');
|
|
363
|
+
|
|
364
|
+
// Switch to NFC-e
|
|
365
|
+
await page.getByText(/NFC-e|Cupom/i).first().click();
|
|
366
|
+
await expect(page.getByText(/Habilitar NFC-e/i).first()).toBeVisible({timeout: 10000});
|
|
367
|
+
|
|
368
|
+
await writeEvidence(page, outputDir, '04-fiscal-nfce', 'Fiscal tab NFC-e visible');
|
|
369
|
+
|
|
370
|
+
// Back to Gerais — values must still be present without re-fetch cascade
|
|
371
|
+
await page.getByText(/Gerais/i).first().click();
|
|
372
|
+
await expect(page.getByText(/Regime tributario|Regime tributário/i).first()).toBeVisible({
|
|
373
|
+
timeout: 10000,
|
|
374
|
+
});
|
|
375
|
+
await expect(page.getByText(/Codigo IBGE|Código IBGE/i).first()).toBeVisible({
|
|
376
|
+
timeout: 5000,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
await writeEvidence(
|
|
380
|
+
page,
|
|
381
|
+
outputDir,
|
|
382
|
+
'05-fiscal-gerais-return',
|
|
383
|
+
'Back to Gerais — values still visible',
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
// Core acceptance: never called marketplace/integrations for pure fiscal
|
|
387
|
+
expect(api.getMarketplaceHits()).toEqual([]);
|
|
388
|
+
|
|
389
|
+
// Configs load should not explode on every tab switch (load-once)
|
|
390
|
+
const configsAfterTabs = api.getConfigsHits().length;
|
|
391
|
+
expect(configsAfterTabs - configsAfterOpen).toBeLessThanOrEqual(1);
|
|
392
|
+
|
|
393
|
+
// No Provider toast / page error from marketplace
|
|
394
|
+
await expect(page.getByText(/Provider not found or access denied/i)).toHaveCount(0);
|
|
395
|
+
const relevantErrors = api
|
|
396
|
+
.getPageErrors()
|
|
397
|
+
.filter(msg => /provider not found|maximum update depth/i.test(msg));
|
|
398
|
+
expect(relevantErrors).toEqual([]);
|
|
399
|
+
|
|
400
|
+
const manifest = writeManifest(outputDir);
|
|
401
|
+
expect(manifest.fluxo).toBe(FLOW_ID);
|
|
402
|
+
expect(manifest.flowchartIds).toEqual(FLOWCHART_IDS);
|
|
403
|
+
expect(manifest.steps.length).toBeGreaterThanOrEqual(5);
|
|
404
|
+
|
|
405
|
+
for (const step of manifest.steps) {
|
|
406
|
+
const pngPath = path.join(outputDir, step.screenshot);
|
|
407
|
+
expect(fs.existsSync(pngPath)).toBe(true);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
});
|