Skip to content

Commit c2fd419

Browse files
authored
Merge branch 'master' into fix/4350-current-time
2 parents 2147de7 + ff3a20e commit c2fd419

40 files changed

+2844
-854
lines changed

e2e/appActions.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -159,24 +159,26 @@ async function expandTreePaneItemByName(page, name) {
159159
* @returns {Promise<CreatedObjectInfo>} An object containing information about the newly created domain object.
160160
*/
161161
async function createPlanFromJSON(page, { name, json, parent = 'mine' }) {
162+
if (!name) {
163+
name = `Plan:${genUuid()}`;
164+
}
165+
162166
const parentUrl = await getHashUrlToDomainObject(page, parent);
163167

164168
// Navigate to the parent object. This is necessary to create the object
165169
// in the correct location, such as a folder, layout, or plot.
166170
await page.goto(`${parentUrl}?hideTree=true`);
167171

168-
//Click the Create button
172+
// Click the Create button
169173
await page.click('button:has-text("Create")');
170174

171175
// Click 'Plan' menu option
172176
await page.click(`li:text("Plan")`);
173177

174178
// Modify the name input field of the domain object to accept 'name'
175-
if (name) {
176-
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
177-
await nameInput.fill("");
178-
await nameInput.fill(name);
179-
}
179+
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
180+
await nameInput.fill("");
181+
await nameInput.fill(name);
180182

181183
// Upload buffer from memory
182184
await page.locator('input#fileElem').setInputFiles({
@@ -194,7 +196,7 @@ async function createPlanFromJSON(page, { name, json, parent = 'mine' }) {
194196
]);
195197

196198
// Wait until the URL is updated
197-
await page.waitForURL(`**/mine/*`);
199+
await page.waitForURL(`**/${parent}/*`);
198200
const uuid = await getFocusedObjectUuid(page);
199201
const objectUrl = await getHashUrlToDomainObject(page, uuid);
200202

e2e/helper/planningUtils.js

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*****************************************************************************
2+
* Open MCT, Copyright (c) 2014-2023, United States Government
3+
* as represented by the Administrator of the National Aeronautics and Space
4+
* Administration. All rights reserved.
5+
*
6+
* Open MCT is licensed under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
* http://www.apache.org/licenses/LICENSE-2.0.
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
* License for the specific language governing permissions and limitations
15+
* under the License.
16+
*
17+
* Open MCT includes source code licensed under additional open source
18+
* licenses. See the Open Source Licenses file (LICENSES.md) included with
19+
* this source code distribution or the Licensing information page available
20+
* at runtime from the About dialog for additional information.
21+
*****************************************************************************/
22+
23+
import { expect } from '../pluginFixtures';
24+
25+
/**
26+
* Asserts that the number of activities in the plan view matches the number of
27+
* activities in the plan data within the specified time bounds. Performs an assertion
28+
* for each activity in the plan data per group, using the earliest activity's
29+
* start time as the start bound and the current activity's end time as the end bound.
30+
* @param {import('@playwright/test').Page} page the page
31+
* @param {object} plan The raw plan json to assert against
32+
* @param {string} objectUrl The URL of the object to assert against (plan or gantt chart)
33+
*/
34+
export async function assertPlanActivities(page, plan, objectUrl) {
35+
const groups = Object.keys(plan);
36+
for (const group of groups) {
37+
for (let i = 0; i < plan[group].length; i++) {
38+
// Set the startBound to the start time of the first activity in the group
39+
const startBound = plan[group][0].start;
40+
// Set the endBound to the end time of the current activity
41+
let endBound = plan[group][i].end;
42+
if (endBound === startBound) {
43+
// Prevent oddities with setting start and end bound equal
44+
// via URL params
45+
endBound += 1;
46+
}
47+
48+
// Switch to fixed time mode with all plan events within the bounds
49+
await page.goto(`${objectUrl}?tc.mode=fixed&tc.startBound=${startBound}&tc.endBound=${endBound}&tc.timeSystem=utc&view=plan.view`);
50+
51+
// Assert that the number of activities in the plan view matches the number of
52+
// activities in the plan data within the specified time bounds
53+
const eventCount = await page.locator('.activity-bounds').count();
54+
expect(eventCount).toEqual(Object.values(plan)
55+
.flat()
56+
.filter(event =>
57+
activitiesWithinTimeBounds(event.start, event.end, startBound, endBound)).length);
58+
}
59+
}
60+
}
61+
62+
/**
63+
* Returns true if the activities time bounds overlap, false otherwise.
64+
* @param {number} start1 the start time of the first activity
65+
* @param {number} end1 the end time of the first activity
66+
* @param {number} start2 the start time of the second activity
67+
* @param {number} end2 the end time of the second activity
68+
* @returns {boolean} true if the activities overlap, false otherwise
69+
*/
70+
function activitiesWithinTimeBounds(start1, end1, start2, end2) {
71+
return (start1 >= start2 && start1 <= end2)
72+
|| (end1 >= start2 && end1 <= end2)
73+
|| (start2 >= start1 && start2 <= end1)
74+
|| (end2 >= start1 && end2 <= end1);
75+
}
76+
77+
/**
78+
* Navigate to the plan view, switch to fixed time mode,
79+
* and set the bounds to span all activities.
80+
* @param {import('@playwright/test').Page} page
81+
* @param {object} planJson
82+
* @param {string} planObjectUrl
83+
*/
84+
export async function setBoundsToSpanAllActivities(page, planJson, planObjectUrl) {
85+
const activities = Object.values(planJson).flat();
86+
// Get the earliest start value
87+
const start = Math.min(...activities.map(activity => activity.start));
88+
// Get the latest end value
89+
const end = Math.max(...activities.map(activity => activity.end));
90+
// Set the start and end bounds to the earliest start and latest end
91+
await page.goto(`${planObjectUrl}?tc.mode=fixed&tc.startBound=${start}&tc.endBound=${end}&tc.timeSystem=utc&view=plan.view`);
92+
}

0 commit comments

Comments
 (0)