@umbraco/playwright-testhelpers 17.0.6 → 17.0.8
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/dist/lib/helpers/ApiHelpers.d.ts +23 -13
- package/dist/lib/helpers/ApiHelpers.js +107 -49
- package/dist/lib/helpers/ApiHelpers.js.map +1 -1
- package/dist/lib/helpers/ContentUiHelper.js +2 -2
- package/dist/lib/helpers/ContentUiHelper.js.map +1 -1
- package/dist/lib/helpers/DataTypeUiHelper.js +4 -3
- package/dist/lib/helpers/DataTypeUiHelper.js.map +1 -1
- package/dist/lib/helpers/LoginApiHelper.d.ts +7 -3
- package/dist/lib/helpers/LoginApiHelper.js +7 -5
- package/dist/lib/helpers/LoginApiHelper.js.map +1 -1
- package/dist/lib/helpers/UiBaseLocators.d.ts +2 -0
- package/dist/lib/helpers/UiBaseLocators.js +15 -2
- package/dist/lib/helpers/UiBaseLocators.js.map +1 -1
- package/dist/lib/helpers/UserApiHelper.d.ts +6 -2
- package/dist/lib/helpers/UserApiHelper.js +1 -1
- package/dist/lib/helpers/UserApiHelper.js.map +1 -1
- package/dist/lib/helpers/UserGroupUiHelper.js +2 -2
- package/dist/lib/helpers/UserGroupUiHelper.js.map +1 -1
- package/dist/lib/helpers/UserUiHelper.d.ts +0 -1
- package/dist/lib/helpers/UserUiHelper.js +0 -2
- package/dist/lib/helpers/UserUiHelper.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -88,30 +88,40 @@ export declare class ApiHelpers {
|
|
|
88
88
|
delete(url: string, data?: object): Promise<import("playwright-core").APIResponse>;
|
|
89
89
|
put(url: string, data?: object): Promise<import("playwright-core").APIResponse>;
|
|
90
90
|
postMultiPartForm(url: string, id: any, name: string, mimeType: string, filePath: any): Promise<import("playwright-core").APIResponse>;
|
|
91
|
-
private getTokenIssuedTime;
|
|
92
|
-
private getTokenExpireTime;
|
|
93
91
|
getRefreshToken(): Promise<any>;
|
|
94
|
-
isAccessTokenValid(): Promise<void | {
|
|
95
|
-
cookie: string;
|
|
96
|
-
accessToken: any;
|
|
97
|
-
refreshToken: any;
|
|
98
|
-
}>;
|
|
99
92
|
private currentDateToEpoch;
|
|
100
93
|
private dateToEpoch;
|
|
101
|
-
refreshAccessToken(userEmail: string, userPassword: string): Promise<
|
|
94
|
+
refreshAccessToken(userEmail: string, userPassword: string): Promise<{
|
|
102
95
|
cookie: string;
|
|
103
|
-
accessToken:
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
accessToken: "" | {
|
|
97
|
+
value: string;
|
|
98
|
+
} | undefined;
|
|
99
|
+
refreshToken: "" | {
|
|
100
|
+
value: string;
|
|
101
|
+
} | undefined;
|
|
102
|
+
} | undefined>;
|
|
103
|
+
private splitCookies;
|
|
106
104
|
updateTokenAndCookie(userEmail: string, userPassword: string): Promise<{
|
|
107
105
|
cookie: string;
|
|
108
|
-
accessToken:
|
|
109
|
-
|
|
106
|
+
accessToken: "" | {
|
|
107
|
+
value: string;
|
|
108
|
+
} | undefined;
|
|
109
|
+
refreshToken: "" | {
|
|
110
|
+
value: string;
|
|
111
|
+
} | undefined;
|
|
110
112
|
}>;
|
|
111
113
|
readFileContent(filePath: any): Promise<any>;
|
|
112
114
|
readLocalBearerToken(): Promise<string>;
|
|
113
115
|
readLocalCookie(): Promise<string>;
|
|
114
116
|
private getLocalStorageToken;
|
|
117
|
+
updateLocalStorageTokens(setCookies: string): Promise<{
|
|
118
|
+
accessToken: "" | {
|
|
119
|
+
value: string;
|
|
120
|
+
} | undefined;
|
|
121
|
+
refreshToken: "" | {
|
|
122
|
+
value: string;
|
|
123
|
+
} | undefined;
|
|
124
|
+
}>;
|
|
115
125
|
private getLocalStorageAuthToken;
|
|
116
126
|
private updateLocalStorage;
|
|
117
127
|
private updateCookie;
|
|
@@ -187,32 +187,35 @@ class ApiHelpers {
|
|
|
187
187
|
};
|
|
188
188
|
return await this.page.request.post(url, options);
|
|
189
189
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
190
|
+
// Currently not used
|
|
191
|
+
// private async getTokenIssuedTime() {
|
|
192
|
+
// const authToken = await this.getLocalStorageAuthToken();
|
|
193
|
+
// return Number(authToken.issued_at);
|
|
194
|
+
// }
|
|
195
|
+
// private async getTokenExpireTime() {
|
|
196
|
+
// const authToken = await this.getLocalStorageAuthToken();
|
|
197
|
+
// return Number(authToken.expires_in);
|
|
198
|
+
// }
|
|
199
|
+
//
|
|
200
|
+
// async isAccessTokenValid() {
|
|
201
|
+
// const tokenTimeIssued = await this.getTokenIssuedTime();
|
|
202
|
+
// const tokenExpireTime = await this.getTokenExpireTime();
|
|
203
|
+
// // Should use a global value
|
|
204
|
+
// const globalTestTimeout: number = 45;
|
|
205
|
+
// // We want to have the date minus the globalTimeout, the reason for this is that while a test is running, the token could expire.
|
|
206
|
+
// // The refresh token lasts for 300 seconds, while the access token lasts for 60 seconds (NOT TOTALLY SURE) this is why we add 240 seconds
|
|
207
|
+
// const tokenRefreshTime = tokenTimeIssued + tokenExpireTime - (globalTestTimeout);
|
|
208
|
+
// // We need the currentTimeInEpoch so we can check if the tokenRefreshTime is close to expiring.
|
|
209
|
+
// const currentTimeInEpoch = await this.currentDateToEpoch();
|
|
210
|
+
//
|
|
211
|
+
// if (tokenRefreshTime <= currentTimeInEpoch) {
|
|
212
|
+
// return await this.refreshAccessToken(umbracoConfig.user.login, umbracoConfig.user.password);
|
|
213
|
+
// }
|
|
214
|
+
// }
|
|
198
215
|
async getRefreshToken() {
|
|
199
216
|
const authToken = await this.getLocalStorageAuthToken();
|
|
200
217
|
return authToken.refresh_token;
|
|
201
218
|
}
|
|
202
|
-
async isAccessTokenValid() {
|
|
203
|
-
const tokenTimeIssued = await this.getTokenIssuedTime();
|
|
204
|
-
const tokenExpireTime = await this.getTokenExpireTime();
|
|
205
|
-
// Should use a global value
|
|
206
|
-
const globalTestTimeout = 45;
|
|
207
|
-
// We want to have the date minus the globalTimeout, the reason for this is that while a test is running, the token could expire.
|
|
208
|
-
// The refresh token lasts for 300 seconds, while the access token lasts for 60 seconds (NOT TOTALLY SURE) this is why we add 240 seconds
|
|
209
|
-
const tokenRefreshTime = tokenTimeIssued + tokenExpireTime - (globalTestTimeout);
|
|
210
|
-
// We need the currentTimeInEpoch so we can check if the tokenRefreshTime is close to expiring.
|
|
211
|
-
const currentTimeInEpoch = await this.currentDateToEpoch();
|
|
212
|
-
if (tokenRefreshTime <= currentTimeInEpoch) {
|
|
213
|
-
return await this.refreshAccessToken(umbraco_config_1.umbracoConfig.user.login, umbraco_config_1.umbracoConfig.user.password);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
219
|
async currentDateToEpoch() {
|
|
217
220
|
const currentTime = new Date(Date.now());
|
|
218
221
|
return await this.dateToEpoch(currentTime);
|
|
@@ -241,19 +244,33 @@ class ApiHelpers {
|
|
|
241
244
|
});
|
|
242
245
|
if (response.status() === 200) {
|
|
243
246
|
const jsonStorageValue = await response.json();
|
|
244
|
-
|
|
247
|
+
const jsonStorageCookie = response.headers()['set-cookie'];
|
|
248
|
+
await this.updateLocalStorage(jsonStorageValue);
|
|
249
|
+
// We get multiple cookies, so we have to split them and then update each of the cookies in our localestorage
|
|
250
|
+
let cookies = this.splitCookies(jsonStorageCookie);
|
|
251
|
+
for (const cookie of cookies) {
|
|
252
|
+
await this.updateCookie(cookie);
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
245
255
|
}
|
|
246
256
|
console.log('Error refreshing access token.');
|
|
247
257
|
return await this.updateTokenAndCookie(userEmail, userPassword);
|
|
248
258
|
}
|
|
259
|
+
splitCookies(cookieString) {
|
|
260
|
+
return cookieString
|
|
261
|
+
.trim()
|
|
262
|
+
.split('\n')
|
|
263
|
+
.filter(line => line.trim())
|
|
264
|
+
.filter(line => !line.includes('expires=Thu, 01 Jan 1970'));
|
|
265
|
+
}
|
|
249
266
|
async updateTokenAndCookie(userEmail, userPassword) {
|
|
250
267
|
const storageStateValues = await this.login.login(userEmail, userPassword);
|
|
251
268
|
await this.updateCookie(storageStateValues.cookie);
|
|
252
269
|
await this.updateLocalStorage(storageStateValues.accessToken);
|
|
253
270
|
return {
|
|
254
271
|
cookie: storageStateValues.cookie,
|
|
255
|
-
accessToken: storageStateValues.accessToken
|
|
256
|
-
refreshToken: storageStateValues.refreshToken
|
|
272
|
+
accessToken: storageStateValues.accessToken,
|
|
273
|
+
refreshToken: storageStateValues.refreshToken,
|
|
257
274
|
};
|
|
258
275
|
}
|
|
259
276
|
async readFileContent(filePath) {
|
|
@@ -299,6 +316,35 @@ class ApiHelpers {
|
|
|
299
316
|
async getLocalStorageToken(localStorage, tokenName) {
|
|
300
317
|
return await localStorage.origins?.[0]?.localStorage?.find(item => item.name === tokenName);
|
|
301
318
|
}
|
|
319
|
+
async updateLocalStorageTokens(setCookies) {
|
|
320
|
+
// Find AccessToken and RefreshToken in CookiesString
|
|
321
|
+
const accessValue = setCookies.match(/__Host-umbAccessToken=([^;]+)/)?.[1];
|
|
322
|
+
const refreshValue = setCookies.match(/__Host-umbRefreshToken=([^;]+)/)?.[1];
|
|
323
|
+
const accessToken = accessValue && { value: accessValue };
|
|
324
|
+
const refreshToken = refreshValue && { value: refreshValue };
|
|
325
|
+
let currentLocalStorageValue = await this.getLocalStorageAuthToken();
|
|
326
|
+
const newIssuedTime = await this.currentDateToEpoch();
|
|
327
|
+
currentLocalStorageValue.access_token = accessToken;
|
|
328
|
+
currentLocalStorageValue.refresh_token = refreshToken;
|
|
329
|
+
currentLocalStorageValue.issued_at = newIssuedTime;
|
|
330
|
+
const filePath = process.env.STORAGE_STAGE_PATH;
|
|
331
|
+
// Updates the user.json file in our CMS project
|
|
332
|
+
if (filePath) {
|
|
333
|
+
try {
|
|
334
|
+
const data = await this.readFileContent(filePath);
|
|
335
|
+
const fileLocalStorageToken = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');
|
|
336
|
+
fileLocalStorageToken.value = JSON.stringify(currentLocalStorageValue);
|
|
337
|
+
// Converts the object to JSON string
|
|
338
|
+
const updatedJsonString = JSON.stringify(data, null, 2);
|
|
339
|
+
// Writes the updated JSON content to the file
|
|
340
|
+
fs.writeFileSync(filePath, updatedJsonString, 'utf-8');
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
console.error('Error updating token:', error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return { accessToken: accessToken, refreshToken: refreshToken };
|
|
347
|
+
}
|
|
302
348
|
async getLocalStorageAuthToken() {
|
|
303
349
|
const currentStorageState = await this.page.context().storageState();
|
|
304
350
|
const currentStorageToken = await this.getLocalStorageToken(currentStorageState, 'umb:userAuthTokenResponse');
|
|
@@ -332,34 +378,46 @@ class ApiHelpers {
|
|
|
332
378
|
}
|
|
333
379
|
}
|
|
334
380
|
async updateCookie(cookieString) {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
// Updates the expires value and converts it to Epoch
|
|
348
|
-
currentCookie.expires = await this.dateToEpoch(new Date(val));
|
|
381
|
+
try {
|
|
382
|
+
// Parse cookie string
|
|
383
|
+
const parts = cookieString.split(';').map(p => p.trim());
|
|
384
|
+
const [nameValue, ...attributes] = parts;
|
|
385
|
+
const [name, value] = nameValue.split('=');
|
|
386
|
+
const cookieName = name.trim();
|
|
387
|
+
// Get current state
|
|
388
|
+
const storageState = await this.page.context().storageState();
|
|
389
|
+
const cookieIndex = storageState.cookies.findIndex(c => c.name === cookieName);
|
|
390
|
+
if (cookieIndex === -1) {
|
|
391
|
+
console.log(`Cookie "${cookieName}" not found`);
|
|
392
|
+
return;
|
|
349
393
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
394
|
+
// Update cookie value
|
|
395
|
+
storageState.cookies[cookieIndex].value = value;
|
|
396
|
+
// Update expires if present
|
|
397
|
+
for (const attr of attributes) {
|
|
398
|
+
if (attr.toLowerCase().startsWith('expires=')) {
|
|
399
|
+
const expiresDate = attr.split('=')[1];
|
|
400
|
+
storageState.cookies[cookieIndex].expires = Date.parse(expiresDate) / 1000;
|
|
401
|
+
}
|
|
358
402
|
}
|
|
359
|
-
|
|
360
|
-
|
|
403
|
+
// Write to file if path exists
|
|
404
|
+
const filePath = process.env.STORAGE_STAGE_PATH;
|
|
405
|
+
if (filePath) {
|
|
406
|
+
const fs = require('fs');
|
|
407
|
+
const fileData = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
408
|
+
const fileCookieIndex = fileData.cookies.findIndex(c => c.name === cookieName);
|
|
409
|
+
if (fileCookieIndex !== -1) {
|
|
410
|
+
fileData.cookies[fileCookieIndex] = storageState.cookies[cookieIndex];
|
|
411
|
+
fs.writeFileSync(filePath, JSON.stringify(fileData, null, 2));
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
console.log(`Cookie "${cookieName}" not found in file`);
|
|
415
|
+
}
|
|
361
416
|
}
|
|
362
417
|
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
console.error('Error updating cookie:', error);
|
|
420
|
+
}
|
|
363
421
|
}
|
|
364
422
|
async revokeAccessToken(cookie, accessToken) {
|
|
365
423
|
return await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/revoke', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiHelpers.js","sourceRoot":"","sources":["../../../lib/helpers/ApiHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {Page} from \"@playwright/test\"\nimport {umbracoConfig} from \"../../umbraco.config\";\nimport {ReportHelper} from \"./ReportHelper\";\nimport {TelemetryDataApiHelper} from \"./TelemetryDataApiHelper\";\nimport {LanguageApiHelper} from \"./LanguageApiHelper\";\nimport {DictionaryApiHelper} from \"./DictionaryApiHelper\";\nimport {RelationTypeApiHelper} from \"./RelationTypeApiHelper\";\nimport {UserGroupApiHelper} from \"./UserGroupApiHelper\";\nimport {TemplateApiHelper} from \"./TemplateApiHelper\";\nimport {AliasHelper} from \"./AliasHelper\";\nimport {DataTypeApiHelper} from \"./DataTypeApiHelper\";\nimport {UserApiHelper} from \"./UserApiHelper\";\nimport {TemporaryFileApiHelper} from \"./TemporaryFileApiHelper\";\nimport {PackageApiHelper} from \"./PackageApiHelper\";\nimport {ScriptApiHelper} from \"./ScriptApiHelper\";\nimport {PartialViewApiHelper} from \"./PartialViewApiHelper\";\nimport {StylesheetApiHelper} from \"./StylesheetApiHelper\";\nimport * as fs from \"fs\";\nimport {LogViewerApiHelper} from \"./LogViewerApiHelper\";\nimport {DocumentTypeApiHelper} from \"./DocumentTypeApiHelper\";\nimport {DocumentApiHelper} from \"./DocumentApiHelper\";\nimport {MediaTypeApiHelper} from \"./MediaTypeApiHelper\";\nimport {MediaApiHelper} from \"./MediaApiHelper\";\nimport {ObjectTypesApiHelper} from \"./ObjectTypesApiHelper\";\nimport {ModelsBuilderApiHelper} from \"./ModelsBuilderApiHelper\";\nimport {HealthCheckApiHelper} from \"./HealthCheckApiHelper\";\nimport {IndexerApiHelper} from \"./IndexerApiHelper\";\nimport {PublishedCacheApiHelper} from \"./PublishedCacheApiHelper\";\nimport {RedirectManagementApiHelper} from './RedirectManagementApiHelper';\nimport {MemberGroupApiHelper} from './MemberGroupApiHelper';\nimport {MemberApiHelper} from './MemberApiHelper';\nimport {MemberTypeApiHelper} from \"./MemberTypeApiHelper\";\nimport {DocumentBlueprintApiHelper} from \"./DocumentBlueprintApiHelper\";\nimport {LoginApiHelper} from \"./LoginApiHelper\";\nimport {WebhookApiHelper} from \"./WebhookApiHelper\";\nimport {MediaDeliveryApiHelper} from './differentAppSettingsHelpers/MediaDeliveryApiHelper';\nimport {ContentDeliveryApiHelper} from \"./differentAppSettingsHelpers/ContentDeliveryApiHelper\";\n\nexport class ApiHelpers {\n baseUrl: string = umbracoConfig.environment.baseUrl;\n page: Page;\n alias: AliasHelper;\n report: ReportHelper;\n telemetry: TelemetryDataApiHelper;\n language: LanguageApiHelper;\n dictionary: DictionaryApiHelper;\n relationType: RelationTypeApiHelper;\n userGroup: UserGroupApiHelper;\n template: TemplateApiHelper;\n dataType: DataTypeApiHelper;\n user: UserApiHelper;\n temporaryFile: TemporaryFileApiHelper;\n documentType: DocumentTypeApiHelper;\n document: DocumentApiHelper;\n package: PackageApiHelper;\n script: ScriptApiHelper;\n partialView: PartialViewApiHelper;\n stylesheet: StylesheetApiHelper;\n logViewer: LogViewerApiHelper;\n mediaType: MediaTypeApiHelper;\n media: MediaApiHelper;\n objectTypes: ObjectTypesApiHelper;\n modelsBuilder: ModelsBuilderApiHelper;\n healthCheck: HealthCheckApiHelper;\n indexer: IndexerApiHelper;\n publishedCache: PublishedCacheApiHelper;\n redirectManagement: RedirectManagementApiHelper;\n memberGroup: MemberGroupApiHelper;\n member: MemberApiHelper;\n memberType: MemberTypeApiHelper;\n documentBlueprint: DocumentBlueprintApiHelper;\n login: LoginApiHelper;\n webhook: WebhookApiHelper;\n mediaDeliveryApi: MediaDeliveryApiHelper;\n contentDeliveryApi: ContentDeliveryApiHelper;\n\n constructor(page: Page) {\n this.page = page;\n this.alias = new AliasHelper();\n this.report = new ReportHelper(this);\n this.telemetry = new TelemetryDataApiHelper(this);\n this.language = new LanguageApiHelper(this);\n this.dictionary = new DictionaryApiHelper(this);\n this.relationType = new RelationTypeApiHelper(this);\n this.userGroup = new UserGroupApiHelper(this);\n this.template = new TemplateApiHelper(this);\n this.dataType = new DataTypeApiHelper(this);\n this.user = new UserApiHelper(this, page);\n this.temporaryFile = new TemporaryFileApiHelper(this);\n this.documentType = new DocumentTypeApiHelper(this);\n this.document = new DocumentApiHelper(this);\n this.package = new PackageApiHelper(this);\n this.script = new ScriptApiHelper(this);\n this.partialView = new PartialViewApiHelper(this);\n this.stylesheet = new StylesheetApiHelper(this);\n this.logViewer = new LogViewerApiHelper(this);\n this.mediaType = new MediaTypeApiHelper(this);\n this.media = new MediaApiHelper(this);\n this.objectTypes = new ObjectTypesApiHelper(this);\n this.modelsBuilder = new ModelsBuilderApiHelper(this);\n this.healthCheck = new HealthCheckApiHelper(this);\n this.indexer = new IndexerApiHelper(this);\n this.publishedCache = new PublishedCacheApiHelper(this);\n this.redirectManagement = new RedirectManagementApiHelper(this);\n this.memberGroup = new MemberGroupApiHelper(this);\n this.member = new MemberApiHelper(this);\n this.memberType = new MemberTypeApiHelper(this);\n this.documentBlueprint = new DocumentBlueprintApiHelper(this);\n this.login = new LoginApiHelper(this, this.page);\n this.webhook = new WebhookApiHelper(this, this.page);\n this.mediaDeliveryApi = new MediaDeliveryApiHelper(this);\n this.contentDeliveryApi = new ContentDeliveryApiHelper(this);\n }\n\n async getAccessToken() {\n const authToken = await this.getLocalStorageAuthToken();\n return authToken.access_token;\n }\n\n async getBearerToken() {\n return 'Bearer ' + await this.getAccessToken();\n }\n\n async getCookie() {\n let someStorage = await this.page.context().storageState();\n let cookieString = \"\";\n for (let cookie of someStorage.cookies) {\n cookieString += cookie.name + '=' + cookie.value + ';';\n }\n return cookieString;\n }\n\n async getHeaders() {\n return {\n 'Authorization': await this.readLocalBearerToken(),\n 'Cookie': await this.readLocalCookie(),\n }\n }\n\n async get(url: string, params?: { [key: string]: string | number | boolean; }, extraHeaders?: { [key: string]: string; }) {\n const headers = await this.getHeaders();\n const allHeaders = { ...headers, ...extraHeaders };\n const options = {\n headers: allHeaders,\n params: params,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.get(url, options);\n }\n\n async saveCodeFile(codeFile) {\n if (codeFile == null) {\n return;\n }\n return await this.post(umbracoConfig.environment.baseUrl + '/umbraco/backoffice/UmbracoApi/CodeFile/PostSave', codeFile);\n }\n\n async post(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.post(url, options);\n }\n\n async delete(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.delete(url, options);\n }\n\n async put(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.put(url, options);\n }\n\n async postMultiPartForm(url: string, id, name: string, mimeType: string, filePath) {\n const options = {\n headers: await this.getHeaders(),\n multipart: {\n Id: id,\n File: {\n name: name,\n mimeType: mimeType,\n buffer: fs.readFileSync(filePath)\n }\n },\n ignoreHTTPSErrors: true\n }\n return await this.page.request.post(url, options);\n }\n\n private async getTokenIssuedTime() {\n const authToken = await this.getLocalStorageAuthToken();\n return Number(authToken.issued_at);\n }\n\n private async getTokenExpireTime() {\n const authToken = await this.getLocalStorageAuthToken();\n return Number(authToken.expires_in);\n }\n\n async getRefreshToken() {\n const authToken = await this.getLocalStorageAuthToken();\n return authToken.refresh_token;\n }\n\n async isAccessTokenValid() {\n const tokenTimeIssued = await this.getTokenIssuedTime();\n const tokenExpireTime = await this.getTokenExpireTime();\n // Should use a global value\n const globalTestTimeout: number = 45;\n // We want to have the date minus the globalTimeout, the reason for this is that while a test is running, the token could expire.\n // The refresh token lasts for 300 seconds, while the access token lasts for 60 seconds (NOT TOTALLY SURE) this is why we add 240 seconds\n const tokenRefreshTime = tokenTimeIssued + tokenExpireTime - (globalTestTimeout);\n // We need the currentTimeInEpoch so we can check if the tokenRefreshTime is close to expiring.\n const currentTimeInEpoch = await this.currentDateToEpoch();\n\n if (tokenRefreshTime <= currentTimeInEpoch) {\n return await this.refreshAccessToken(umbracoConfig.user.login, umbracoConfig.user.password);\n }\n }\n\n private async currentDateToEpoch() {\n const currentTime = new Date(Date.now());\n return await this.dateToEpoch(currentTime);\n }\n\n private async dateToEpoch(date: Date) {\n const dateToEpoch = date.getTime();\n // The epoch is in milliseconds, but we want it to be in seconds(Like it is in the token).\n const millisecondsToSeconds = dateToEpoch / 1000;\n // There is no need to have anything after .\n return Number(millisecondsToSeconds.toString().split('.')[0]);\n }\n\n async refreshAccessToken(userEmail: string, userPassword: string) {\n const response = await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/token', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: await this.readLocalCookie(),\n Origin: this.baseUrl\n },\n form:\n {\n grant_type: 'refresh_token',\n client_id: 'umbraco-back-office',\n redirect_uri: this.baseUrl + '/umbraco/oauth_complete',\n refresh_token: await this.getRefreshToken()\n },\n ignoreHTTPSErrors: true\n });\n\n if (response.status() === 200) {\n const jsonStorageValue = await response.json();\n return await this.updateLocalStorage(jsonStorageValue);\n }\n console.log('Error refreshing access token.');\n return await this.updateTokenAndCookie(userEmail, userPassword);\n }\n\n async updateTokenAndCookie(userEmail: string, userPassword: string) {\n const storageStateValues = await this.login.login(userEmail, userPassword);\n await this.updateCookie(storageStateValues.cookie);\n await this.updateLocalStorage(storageStateValues.accessToken);\n return {\n cookie: storageStateValues.cookie,\n accessToken: storageStateValues.accessToken.access_token,\n refreshToken: storageStateValues.refreshToken.refresh_token\n };\n }\n\n async readFileContent(filePath) {\n try {\n const jsonString = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(jsonString);\n } catch (error) {\n console.log('Error reading file:', error);\n throw error;\n }\n }\n\n async readLocalBearerToken() {\n const filePath = process.env.STORAGE_STAGE_PATH;\n if (!filePath) {\n return await this.getBearerToken();\n }\n\n try {\n const data = await JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const localStorageItem = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');\n const parsedValue = await JSON.parse(localStorageItem.value);\n return `Bearer ${parsedValue.access_token}`;\n } catch {\n // If the file is not found, return the current access token from the page context\n return await this.getBearerToken();\n }\n }\n\n async readLocalCookie() {\n const filePath = process.env.STORAGE_STAGE_PATH;\n if (!filePath) {\n return await this.getCookie();\n }\n\n try {\n const data = await JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n return await data.cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; ') + ';';\n } catch {\n // If the file is not found, return the current cookie from the page context\n return await this.getCookie();\n }\n }\n\n private async getLocalStorageToken(localStorage: any, tokenName: string) {\n return await localStorage.origins?.[0]?.localStorage?.find(item => item.name === tokenName);\n }\n\n private async getLocalStorageAuthToken(){\n const currentStorageState = await this.page.context().storageState();\n const currentStorageToken = await this.getLocalStorageToken(currentStorageState, 'umb:userAuthTokenResponse');\n return JSON.parse(currentStorageToken.value);\n }\n\n private async updateLocalStorage(localStorageValue) {\n // Parse the existing token value and update its fields\n let currentLocalStorageValue = await this.getLocalStorageAuthToken();\n const newIssuedTime = await this.currentDateToEpoch();\n\n currentLocalStorageValue.access_token = localStorageValue.access_token;\n currentLocalStorageValue.refresh_token = localStorageValue.refresh_token;\n currentLocalStorageValue.issued_at = newIssuedTime;\n currentLocalStorageValue.scope = localStorageValue.scope;\n currentLocalStorageValue.token_type = localStorageValue.token_type;\n currentLocalStorageValue.expires_in = localStorageValue.expires_in.toString();\n\n const filePath = process.env.STORAGE_STAGE_PATH;\n // Updates the user.json file in our CMS project\n if (filePath) {\n try {\n const data = await this.readFileContent(filePath);\n const fileLocalStorageToken = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');\n fileLocalStorageToken.value = JSON.stringify(currentLocalStorageValue);\n // Converts the object to JSON string\n const updatedJsonString = JSON.stringify(data, null, 2);\n // Writes the updated JSON content to the file\n fs.writeFileSync(filePath, updatedJsonString, 'utf-8');\n } catch (error) {\n console.error('Error updating token:', error);\n }\n }\n }\n\n private async updateCookie(cookieString: string) {\n const currentStorageState = await this.page.context().storageState();\n let currentCookie = currentStorageState.cookies[0];\n\n const parts = cookieString.split(';').map(part => part.trim());\n // Extract the main key-value pair\n const [nameValue, ...attributes] = parts;\n const [, value] = nameValue.split('=');\n // Updates the cookie value\n currentCookie.value = value;\n // Process each attribute\n for (const attr of attributes) {\n const [key, val] = attr.split('=');\n if (key.trim().toLowerCase() === 'expires') {\n // Updates the expires value and converts it to Epoch\n currentCookie.expires = await this.dateToEpoch(new Date(val));\n }\n }\n\n const filePath = process.env.STORAGE_STAGE_PATH;\n\n if (filePath) {\n try {\n const data = await this.readFileContent(filePath);\n data.cookies[0] = currentCookie;\n const updatedJsonString = JSON.stringify(data, null, 2);\n fs.writeFileSync(filePath, updatedJsonString, 'utf-8');\n } catch (error) {\n console.error('Error updating cookie:', error);\n }\n }\n }\n\n async revokeAccessToken(cookie: string, accessToken: string) {\n return await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/revoke', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: cookie,\n Origin: this.baseUrl\n },\n form:\n {\n token: accessToken,\n token_type_hint: 'access_token',\n client_id: 'umbraco-back-office'\n },\n ignoreHTTPSErrors: true\n });\n }\n\n async revokeRefreshToken(cookie: string, refreshToken: string) {\n return await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/revoke', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: cookie,\n Origin: this.baseUrl\n },\n form:\n {\n token: refreshToken,\n token_type_hint: 'refresh_token',\n client_id: 'umbraco-back-office'\n },\n ignoreHTTPSErrors: true\n });\n }\n\n async loginToAdminUser(testUserCookie: string, testUserAccessToken: string, testUserRefreshToken: string) {\n await this.revokeAccessToken(testUserCookie, testUserAccessToken);\n await this.revokeRefreshToken(testUserCookie, testUserRefreshToken);\n await this.updateTokenAndCookie(umbracoConfig.user.login, umbracoConfig.user.password);\n }\n\n async getCurrentTimePlusMinute(minute: number = 1) {\n const now = new Date();\n now.setMinutes(now.getMinutes() + minute); // Add one minute\n\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n \n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n async convertDateFormat(dateString: string) {\n return new Date(dateString).toLocaleString(\"en-US\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\",\n hour12: true,\n });\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"ApiHelpers.js","sourceRoot":"","sources":["../../../lib/helpers/ApiHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {Page} from \"@playwright/test\"\nimport {umbracoConfig} from \"../../umbraco.config\";\nimport {ReportHelper} from \"./ReportHelper\";\nimport {TelemetryDataApiHelper} from \"./TelemetryDataApiHelper\";\nimport {LanguageApiHelper} from \"./LanguageApiHelper\";\nimport {DictionaryApiHelper} from \"./DictionaryApiHelper\";\nimport {RelationTypeApiHelper} from \"./RelationTypeApiHelper\";\nimport {UserGroupApiHelper} from \"./UserGroupApiHelper\";\nimport {TemplateApiHelper} from \"./TemplateApiHelper\";\nimport {AliasHelper} from \"./AliasHelper\";\nimport {DataTypeApiHelper} from \"./DataTypeApiHelper\";\nimport {UserApiHelper} from \"./UserApiHelper\";\nimport {TemporaryFileApiHelper} from \"./TemporaryFileApiHelper\";\nimport {PackageApiHelper} from \"./PackageApiHelper\";\nimport {ScriptApiHelper} from \"./ScriptApiHelper\";\nimport {PartialViewApiHelper} from \"./PartialViewApiHelper\";\nimport {StylesheetApiHelper} from \"./StylesheetApiHelper\";\nimport * as fs from \"fs\";\nimport {LogViewerApiHelper} from \"./LogViewerApiHelper\";\nimport {DocumentTypeApiHelper} from \"./DocumentTypeApiHelper\";\nimport {DocumentApiHelper} from \"./DocumentApiHelper\";\nimport {MediaTypeApiHelper} from \"./MediaTypeApiHelper\";\nimport {MediaApiHelper} from \"./MediaApiHelper\";\nimport {ObjectTypesApiHelper} from \"./ObjectTypesApiHelper\";\nimport {ModelsBuilderApiHelper} from \"./ModelsBuilderApiHelper\";\nimport {HealthCheckApiHelper} from \"./HealthCheckApiHelper\";\nimport {IndexerApiHelper} from \"./IndexerApiHelper\";\nimport {PublishedCacheApiHelper} from \"./PublishedCacheApiHelper\";\nimport {RedirectManagementApiHelper} from './RedirectManagementApiHelper';\nimport {MemberGroupApiHelper} from './MemberGroupApiHelper';\nimport {MemberApiHelper} from './MemberApiHelper';\nimport {MemberTypeApiHelper} from \"./MemberTypeApiHelper\";\nimport {DocumentBlueprintApiHelper} from \"./DocumentBlueprintApiHelper\";\nimport {LoginApiHelper} from \"./LoginApiHelper\";\nimport {WebhookApiHelper} from \"./WebhookApiHelper\";\nimport {MediaDeliveryApiHelper} from './differentAppSettingsHelpers/MediaDeliveryApiHelper';\nimport {ContentDeliveryApiHelper} from \"./differentAppSettingsHelpers/ContentDeliveryApiHelper\";\n\nexport class ApiHelpers {\n baseUrl: string = umbracoConfig.environment.baseUrl;\n page: Page;\n alias: AliasHelper;\n report: ReportHelper;\n telemetry: TelemetryDataApiHelper;\n language: LanguageApiHelper;\n dictionary: DictionaryApiHelper;\n relationType: RelationTypeApiHelper;\n userGroup: UserGroupApiHelper;\n template: TemplateApiHelper;\n dataType: DataTypeApiHelper;\n user: UserApiHelper;\n temporaryFile: TemporaryFileApiHelper;\n documentType: DocumentTypeApiHelper;\n document: DocumentApiHelper;\n package: PackageApiHelper;\n script: ScriptApiHelper;\n partialView: PartialViewApiHelper;\n stylesheet: StylesheetApiHelper;\n logViewer: LogViewerApiHelper;\n mediaType: MediaTypeApiHelper;\n media: MediaApiHelper;\n objectTypes: ObjectTypesApiHelper;\n modelsBuilder: ModelsBuilderApiHelper;\n healthCheck: HealthCheckApiHelper;\n indexer: IndexerApiHelper;\n publishedCache: PublishedCacheApiHelper;\n redirectManagement: RedirectManagementApiHelper;\n memberGroup: MemberGroupApiHelper;\n member: MemberApiHelper;\n memberType: MemberTypeApiHelper;\n documentBlueprint: DocumentBlueprintApiHelper;\n login: LoginApiHelper;\n webhook: WebhookApiHelper;\n mediaDeliveryApi: MediaDeliveryApiHelper;\n contentDeliveryApi: ContentDeliveryApiHelper;\n\n constructor(page: Page) {\n this.page = page;\n this.alias = new AliasHelper();\n this.report = new ReportHelper(this);\n this.telemetry = new TelemetryDataApiHelper(this);\n this.language = new LanguageApiHelper(this);\n this.dictionary = new DictionaryApiHelper(this);\n this.relationType = new RelationTypeApiHelper(this);\n this.userGroup = new UserGroupApiHelper(this);\n this.template = new TemplateApiHelper(this);\n this.dataType = new DataTypeApiHelper(this);\n this.user = new UserApiHelper(this, page);\n this.temporaryFile = new TemporaryFileApiHelper(this);\n this.documentType = new DocumentTypeApiHelper(this);\n this.document = new DocumentApiHelper(this);\n this.package = new PackageApiHelper(this);\n this.script = new ScriptApiHelper(this);\n this.partialView = new PartialViewApiHelper(this);\n this.stylesheet = new StylesheetApiHelper(this);\n this.logViewer = new LogViewerApiHelper(this);\n this.mediaType = new MediaTypeApiHelper(this);\n this.media = new MediaApiHelper(this);\n this.objectTypes = new ObjectTypesApiHelper(this);\n this.modelsBuilder = new ModelsBuilderApiHelper(this);\n this.healthCheck = new HealthCheckApiHelper(this);\n this.indexer = new IndexerApiHelper(this);\n this.publishedCache = new PublishedCacheApiHelper(this);\n this.redirectManagement = new RedirectManagementApiHelper(this);\n this.memberGroup = new MemberGroupApiHelper(this);\n this.member = new MemberApiHelper(this);\n this.memberType = new MemberTypeApiHelper(this);\n this.documentBlueprint = new DocumentBlueprintApiHelper(this);\n this.login = new LoginApiHelper(this, this.page);\n this.webhook = new WebhookApiHelper(this, this.page);\n this.mediaDeliveryApi = new MediaDeliveryApiHelper(this);\n this.contentDeliveryApi = new ContentDeliveryApiHelper(this);\n }\n\n async getAccessToken() {\n const authToken = await this.getLocalStorageAuthToken();\n return authToken.access_token;\n }\n\n async getBearerToken() {\n return 'Bearer ' + await this.getAccessToken();\n }\n\n async getCookie() {\n let someStorage = await this.page.context().storageState();\n let cookieString = \"\";\n for (let cookie of someStorage.cookies) {\n cookieString += cookie.name + '=' + cookie.value + ';';\n }\n return cookieString;\n }\n\n async getHeaders() {\n return {\n 'Authorization': await this.readLocalBearerToken(),\n 'Cookie': await this.readLocalCookie(),\n }\n }\n\n async get(url: string, params?: { [key: string]: string | number | boolean; }, extraHeaders?: { [key: string]: string; }) {\n const headers = await this.getHeaders();\n const allHeaders = {...headers, ...extraHeaders};\n const options = {\n headers: allHeaders,\n params: params,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.get(url, options);\n }\n\n async saveCodeFile(codeFile) {\n if (codeFile == null) {\n return;\n }\n return await this.post(umbracoConfig.environment.baseUrl + '/umbraco/backoffice/UmbracoApi/CodeFile/PostSave', codeFile);\n }\n\n async post(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.post(url, options);\n }\n\n async delete(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.delete(url, options);\n }\n\n async put(url: string, data?: object) {\n const options = {\n headers: await this.getHeaders(),\n data: data,\n ignoreHTTPSErrors: true\n }\n return await this.page.request.put(url, options);\n }\n\n async postMultiPartForm(url: string, id, name: string, mimeType: string, filePath) {\n const options = {\n headers: await this.getHeaders(),\n multipart: {\n Id: id,\n File: {\n name: name,\n mimeType: mimeType,\n buffer: fs.readFileSync(filePath)\n }\n },\n ignoreHTTPSErrors: true\n }\n return await this.page.request.post(url, options);\n }\n\n // Currently not used\n // private async getTokenIssuedTime() {\n // const authToken = await this.getLocalStorageAuthToken();\n // return Number(authToken.issued_at);\n // }\n // private async getTokenExpireTime() {\n // const authToken = await this.getLocalStorageAuthToken();\n // return Number(authToken.expires_in);\n // }\n //\n // async isAccessTokenValid() {\n // const tokenTimeIssued = await this.getTokenIssuedTime();\n // const tokenExpireTime = await this.getTokenExpireTime();\n // // Should use a global value\n // const globalTestTimeout: number = 45;\n // // We want to have the date minus the globalTimeout, the reason for this is that while a test is running, the token could expire.\n // // The refresh token lasts for 300 seconds, while the access token lasts for 60 seconds (NOT TOTALLY SURE) this is why we add 240 seconds\n // const tokenRefreshTime = tokenTimeIssued + tokenExpireTime - (globalTestTimeout);\n // // We need the currentTimeInEpoch so we can check if the tokenRefreshTime is close to expiring.\n // const currentTimeInEpoch = await this.currentDateToEpoch();\n //\n // if (tokenRefreshTime <= currentTimeInEpoch) {\n // return await this.refreshAccessToken(umbracoConfig.user.login, umbracoConfig.user.password);\n // }\n // }\n async getRefreshToken() {\n const authToken = await this.getLocalStorageAuthToken();\n return authToken.refresh_token;\n }\n\n private async currentDateToEpoch() {\n const currentTime = new Date(Date.now());\n return await this.dateToEpoch(currentTime);\n }\n\n private async dateToEpoch(date: Date) {\n const dateToEpoch = date.getTime();\n // The epoch is in milliseconds, but we want it to be in seconds(Like it is in the token).\n const millisecondsToSeconds = dateToEpoch / 1000;\n // There is no need to have anything after .\n return Number(millisecondsToSeconds.toString().split('.')[0]);\n }\n\n async refreshAccessToken(userEmail: string, userPassword: string) {\n const response = await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/token', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: await this.readLocalCookie(),\n Origin: this.baseUrl\n },\n form:\n {\n grant_type: 'refresh_token',\n client_id: 'umbraco-back-office',\n redirect_uri: this.baseUrl + '/umbraco/oauth_complete',\n refresh_token: await this.getRefreshToken()\n },\n ignoreHTTPSErrors: true\n });\n\n if (response.status() === 200) {\n const jsonStorageValue = await response.json();\n const jsonStorageCookie = response.headers()['set-cookie'];\n await this.updateLocalStorage(jsonStorageValue);\n // We get multiple cookies, so we have to split them and then update each of the cookies in our localestorage \n let cookies = this.splitCookies(jsonStorageCookie);\n for (const cookie of cookies) {\n await this.updateCookie(cookie);\n }\n return;\n }\n console.log('Error refreshing access token.');\n return await this.updateTokenAndCookie(userEmail, userPassword);\n }\n\n private splitCookies(cookieString: string): string[] {\n return cookieString\n .trim()\n .split('\\n')\n .filter(line => line.trim())\n .filter(line => !line.includes('expires=Thu, 01 Jan 1970'));\n }\n\n async updateTokenAndCookie(userEmail: string, userPassword: string) {\n const storageStateValues = await this.login.login(userEmail, userPassword);\n await this.updateCookie(storageStateValues.cookie);\n await this.updateLocalStorage(storageStateValues.accessToken);\n return {\n cookie: storageStateValues.cookie,\n accessToken: storageStateValues.accessToken,\n refreshToken: storageStateValues.refreshToken,\n };\n }\n\n async readFileContent(filePath) {\n try {\n const jsonString = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(jsonString);\n } catch (error) {\n console.log('Error reading file:', error);\n throw error;\n }\n }\n\n async readLocalBearerToken() {\n const filePath = process.env.STORAGE_STAGE_PATH;\n if (!filePath) {\n return await this.getBearerToken();\n }\n\n try {\n const data = await JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const localStorageItem = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');\n const parsedValue = await JSON.parse(localStorageItem.value);\n return `Bearer ${parsedValue.access_token}`;\n } catch {\n // If the file is not found, return the current access token from the page context\n return await this.getBearerToken();\n }\n }\n\n async readLocalCookie() {\n const filePath = process.env.STORAGE_STAGE_PATH;\n if (!filePath) {\n return await this.getCookie();\n }\n\n try {\n const data = await JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n return await data.cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; ') + ';';\n } catch {\n // If the file is not found, return the current cookie from the page context\n return await this.getCookie();\n }\n }\n\n private async getLocalStorageToken(localStorage: any, tokenName: string) {\n return await localStorage.origins?.[0]?.localStorage?.find(item => item.name === tokenName);\n }\n\n async updateLocalStorageTokens(setCookies: string) {\n // Find AccessToken and RefreshToken in CookiesString\n const accessValue = setCookies.match(/__Host-umbAccessToken=([^;]+)/)?.[1];\n const refreshValue = setCookies.match(/__Host-umbRefreshToken=([^;]+)/)?.[1];\n const accessToken = accessValue && {value: accessValue};\n const refreshToken = refreshValue && {value: refreshValue};\n\n let currentLocalStorageValue = await this.getLocalStorageAuthToken();\n const newIssuedTime = await this.currentDateToEpoch();\n\n currentLocalStorageValue.access_token = accessToken;\n currentLocalStorageValue.refresh_token = refreshToken;\n currentLocalStorageValue.issued_at = newIssuedTime;\n\n const filePath = process.env.STORAGE_STAGE_PATH;\n // Updates the user.json file in our CMS project\n if (filePath) {\n try {\n const data = await this.readFileContent(filePath);\n const fileLocalStorageToken = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');\n fileLocalStorageToken.value = JSON.stringify(currentLocalStorageValue);\n // Converts the object to JSON string\n const updatedJsonString = JSON.stringify(data, null, 2);\n // Writes the updated JSON content to the file\n fs.writeFileSync(filePath, updatedJsonString, 'utf-8');\n } catch (error) {\n console.error('Error updating token:', error);\n }\n }\n return {accessToken: accessToken, refreshToken: refreshToken};\n }\n\n private async getLocalStorageAuthToken() {\n const currentStorageState = await this.page.context().storageState();\n const currentStorageToken = await this.getLocalStorageToken(currentStorageState, 'umb:userAuthTokenResponse');\n return JSON.parse(currentStorageToken.value);\n }\n\n private async updateLocalStorage(localStorageValue) {\n // Parse the existing token value and update its fields\n let currentLocalStorageValue = await this.getLocalStorageAuthToken();\n const newIssuedTime = await this.currentDateToEpoch();\n\n currentLocalStorageValue.access_token = localStorageValue.access_token;\n currentLocalStorageValue.refresh_token = localStorageValue.refresh_token;\n currentLocalStorageValue.issued_at = newIssuedTime;\n currentLocalStorageValue.scope = localStorageValue.scope;\n currentLocalStorageValue.token_type = localStorageValue.token_type;\n currentLocalStorageValue.expires_in = localStorageValue.expires_in.toString();\n\n const filePath = process.env.STORAGE_STAGE_PATH;\n // Updates the user.json file in our CMS project\n if (filePath) {\n try {\n const data = await this.readFileContent(filePath);\n const fileLocalStorageToken = await this.getLocalStorageToken(data, 'umb:userAuthTokenResponse');\n fileLocalStorageToken.value = JSON.stringify(currentLocalStorageValue);\n // Converts the object to JSON string\n const updatedJsonString = JSON.stringify(data, null, 2);\n // Writes the updated JSON content to the file\n fs.writeFileSync(filePath, updatedJsonString, 'utf-8');\n } catch (error) {\n console.error('Error updating token:', error);\n }\n }\n }\n\n private async updateCookie(cookieString: string) {\n try {\n // Parse cookie string\n const parts = cookieString.split(';').map(p => p.trim());\n const [nameValue, ...attributes] = parts;\n const [name, value] = nameValue.split('=');\n const cookieName = name.trim();\n\n // Get current state\n const storageState = await this.page.context().storageState();\n const cookieIndex = storageState.cookies.findIndex(c => c.name === cookieName);\n\n if (cookieIndex === -1) {\n console.log(`Cookie \"${cookieName}\" not found`);\n return;\n }\n\n // Update cookie value\n storageState.cookies[cookieIndex].value = value;\n\n // Update expires if present\n for (const attr of attributes) {\n if (attr.toLowerCase().startsWith('expires=')) {\n const expiresDate = attr.split('=')[1];\n storageState.cookies[cookieIndex].expires = Date.parse(expiresDate) / 1000;\n }\n }\n\n // Write to file if path exists\n const filePath = process.env.STORAGE_STAGE_PATH;\n if (filePath) {\n const fs = require('fs');\n const fileData = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n\n const fileCookieIndex = fileData.cookies.findIndex(c => c.name === cookieName);\n\n if (fileCookieIndex !== -1) {\n fileData.cookies[fileCookieIndex] = storageState.cookies[cookieIndex];\n fs.writeFileSync(filePath, JSON.stringify(fileData, null, 2));\n } else {\n console.log(`Cookie \"${cookieName}\" not found in file`);\n }\n }\n } catch (error) {\n console.error('Error updating cookie:', error);\n }\n }\n\n async revokeAccessToken(cookie: string, accessToken: string) {\n return await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/revoke', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: cookie,\n Origin: this.baseUrl\n },\n form:\n {\n token: accessToken,\n token_type_hint: 'access_token',\n client_id: 'umbraco-back-office'\n },\n ignoreHTTPSErrors: true\n });\n }\n\n async revokeRefreshToken(cookie: string, refreshToken: string) {\n return await this.page.request.post(this.baseUrl + '/umbraco/management/api/v1/security/back-office/revoke', {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Cookie: cookie,\n Origin: this.baseUrl\n },\n form:\n {\n token: refreshToken,\n token_type_hint: 'refresh_token',\n client_id: 'umbraco-back-office'\n },\n ignoreHTTPSErrors: true\n });\n }\n\n async loginToAdminUser(testUserCookie: string, testUserAccessToken: string, testUserRefreshToken: string) {\n await this.revokeAccessToken(testUserCookie, testUserAccessToken);\n await this.revokeRefreshToken(testUserCookie, testUserRefreshToken);\n await this.updateTokenAndCookie(umbracoConfig.user.login, umbracoConfig.user.password);\n }\n\n async getCurrentTimePlusMinute(minute: number = 1) {\n const now = new Date();\n now.setMinutes(now.getMinutes() + minute); // Add one minute\n\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n\n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n async convertDateFormat(dateString: string) {\n return new Date(dateString).toLocaleString(\"en-US\", {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"numeric\",\n second: \"numeric\",\n hour12: true,\n });\n }\n}"]}
|
|
@@ -583,7 +583,7 @@ class ContentUiHelper extends UiBaseLocators_1.UiBaseLocators {
|
|
|
583
583
|
await (0, test_1.expect)(this.documentTreeItem.locator('[label="' + parentName + '"]').getByLabel(childName)).toBeVisible({ visible: isVisible });
|
|
584
584
|
}
|
|
585
585
|
async removeContentPicker(contentPickerName) {
|
|
586
|
-
const contentPickerLocator = this.
|
|
586
|
+
const contentPickerLocator = this.entityItem.filter({ has: this.page.locator('[name="' + contentPickerName + '"]') });
|
|
587
587
|
await contentPickerLocator.hover();
|
|
588
588
|
await contentPickerLocator.getByLabel('Remove').click();
|
|
589
589
|
await this.clickConfirmRemoveButton();
|
|
@@ -645,7 +645,7 @@ class ContentUiHelper extends UiBaseLocators_1.UiBaseLocators {
|
|
|
645
645
|
await this.sidebarModal.getByText(memberName, { exact: true }).click();
|
|
646
646
|
}
|
|
647
647
|
async removeMemberPickerByName(memberName) {
|
|
648
|
-
const mediaPickerLocator = this.
|
|
648
|
+
const mediaPickerLocator = this.entityItem.filter({ has: this.page.locator('[name="' + memberName + '"]') });
|
|
649
649
|
await mediaPickerLocator.hover();
|
|
650
650
|
await mediaPickerLocator.getByLabel('Remove').click();
|
|
651
651
|
await this.clickConfirmRemoveButton();
|