-
Notifications
You must be signed in to change notification settings - Fork 11
/
Navigation.ts
162 lines (134 loc) · 6.29 KB
/
Navigation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import * as playwright from "playwright";
import { isPageElement } from "../domain/SharedLogic";
import { D365Selectors } from "../domain/D365Selectors";
import { EnsureXrmGetter } from "./Global";
import { XrmUiTest } from "./XrmUITest";
/**
* Define behavior on navigation, for example handling of blocking popups (e.g. "Do you really want to leave this page?"")
*/
export interface NavigationSettings {
/**
* Define whether to confirm or to cancel dialogs that occur on navigation
*/
popUpAction?: "confirm" | "cancel";
}
/**
* Define behaviour for opening forms
*/
export interface FormNavigationSettings extends NavigationSettings {
/**
* Define the ID of the form to open
*/
formId?: string;
}
/**
* Module for navigating in D365
*/
export class Navigation {
private _page: playwright.Page;
constructor(private xrmUiTest: XrmUiTest) {
this._page = xrmUiTest.page;
this.xrmUiTest = xrmUiTest;
}
private async HandlePopUpOnNavigation (navigationPromise: Promise<playwright.Response | Xrm.Async.PromiseLike<Xrm.Navigation.OpenFormResult>>, settings: NavigationSettings) {
const defaultSettings: NavigationSettings = {
popUpAction: "cancel"
};
const safeSettings = {
...defaultSettings,
...settings
};
const popUpButton = safeSettings.popUpAction === "cancel"
? D365Selectors.PopUp.cancel
: D365Selectors.PopUp.confirm;
const result = await Promise.race([
navigationPromise,
// Catch dialogs that block navigation
this._page.waitForSelector(popUpButton, { timeout: this.xrmUiTest.settings.timeout })
]);
if (isPageElement(result)) {
await Promise.all([
navigationPromise,
result.click()
]);
}
}
/**
* Opens a create form for the specified entity
*
* @param entityName The entity to open the form for
* @param settings How to handle dialogs that prevent navigation. Cancel discards the dialog, confirm accepts it. Default is discarding it.
* @returns Promise which resolves once form is fully loaded
*/
openCreateForm = async (entityName: string, settings?: FormNavigationSettings) => {
await EnsureXrmGetter(this._page);
const navigationPromise = this._page.evaluate(([entityName, formId]) => {
const xrm = window.oss_FindXrm();
return xrm.Navigation.openForm({ entityName: entityName, formId: formId ? formId : undefined });
}, [entityName, settings?.formId]);
await this.HandlePopUpOnNavigation(navigationPromise, settings);
await this.xrmUiTest.waitForIdleness();
}
/**
* Opens an update form for an existing record
*
* @param entityName The entity to open the form for
* @param entityId The id of the record to open
* @param settings How to handle dialogs that prevent navigation. Cancel discards the dialog, confirm accepts it. Default is discarding it.
* @returns Promise which resolves once form is fully loaded
*/
openUpdateForm = async (entityName: string, entityId: string, settings?: FormNavigationSettings) => {
await EnsureXrmGetter(this._page);
const navigationPromise = this._page.evaluate(([ entityName, entityId, formId ]) => {
const xrm = window.oss_FindXrm();
return xrm.Navigation.openForm({ entityName: entityName, entityId: entityId, formId: formId ? formId : undefined });
}, [entityName, entityId, settings?.formId]);
await this.HandlePopUpOnNavigation(navigationPromise, settings);
await this.xrmUiTest.waitForIdleness();
}
/**
* Navigate to the specified page
*
* @param pageInput Define where to navigate to (entity record, entity list or html web resource)
* @param navigationOptions Define whether to navigate inline or in a dialog
* @param settings How to handle dialogs that prevent navigation. Cancel discards the dialog, confirm accepts it. Default is discarding it.
* @returns Promise which resolves once the page is fully loaded
*/
navigateTo = async (pageInput: Xrm.Navigation.PageInputEntityRecord | Xrm.Navigation.PageInputEntityList | Xrm.Navigation.PageInputHtmlWebResource, navigationOptions?: Xrm.Navigation.NavigationOptions, settings?: NavigationSettings) => {
await EnsureXrmGetter(this._page);
const navigationPromise = this._page.evaluate(([ pageInput, navigationOptions ]) => {
const xrm = window.oss_FindXrm();
return xrm.Navigation.navigateTo(pageInput, navigationOptions);
}, [ pageInput, navigationOptions ] as [Xrm.Navigation.PageInputEntityRecord | Xrm.Navigation.PageInputEntityList | Xrm.Navigation.PageInputHtmlWebResource, Xrm.Navigation.NavigationOptions]);
await this.HandlePopUpOnNavigation(navigationPromise, settings);
await this.xrmUiTest.waitForIdleness();
}
/**
* Opens a quick create form for the specified entity
*
* @param entityName The entity to open the form for
* @returns Promise which resolves once form is fully loaded
*/
openQuickCreate = async (entityName: string) => {
await EnsureXrmGetter(this._page);
await this._page.evaluate((entityName: string) => {
const xrm = window.oss_FindXrm();
return xrm.Navigation.openForm({ entityName: entityName, useQuickCreateForm: true });
}, entityName);
await this.xrmUiTest.waitForIdleness();
}
/**
* Opens the specified UCI app
*
* @param appId The id of the app to open
* @param settings How to handle dialogs that prevent navigation. Cancel discards the dialog, confirm accepts it. Default is discarding it.
* @returns Promise which resolves once the app is fully loaded
*/
openAppById = async(appId: string, settings?: NavigationSettings) => {
this.xrmUiTest.AppId = appId;
const navigationUrl = this.xrmUiTest.buildUrl(this.xrmUiTest.crmUrl, appId);
const navigationPromise = this._page.goto(navigationUrl, { waitUntil: "load", timeout: this.xrmUiTest.settings.timeout });
await this.HandlePopUpOnNavigation(navigationPromise, settings);
await this.xrmUiTest.waitForIdleness();
}
}