Skip to content

Commit 758a144

Browse files
authored
Merge branch 'master' into fix-iimagery-vulnerability
2 parents aa35068 + 3aaa0f0 commit 758a144

11 files changed

Lines changed: 207 additions & 149 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*****************************************************************************
2+
* Open MCT, Copyright (c) 2014-2024, 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+
// This should be used to install the Example User with multiple roles
24+
document.addEventListener('DOMContentLoaded', () => {
25+
const openmct = window.openmct;
26+
openmct.install(
27+
openmct.plugins.example.ExampleUser({
28+
autoLoginUser: 'mct-user',
29+
statusRoles: ['flight', 'driver'],
30+
roles: ['flight', 'driver']
31+
})
32+
);
33+
});

e2e/tests/functional/missionStatus.e2e.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ test.describe('Mission Status @addInit', () => {
3434
test.beforeEach(async ({ page }) => {
3535
// FIXME: determine if plugins will be added to index.html or need to be injected
3636
await page.addInitScript({
37-
path: fileURLToPath(new URL('../../helper/addInitExampleUser.js', import.meta.url))
37+
path: fileURLToPath(
38+
new URL('../../helper/addInitExampleUserMultipleRoles.js', import.meta.url)
39+
)
3840
});
3941
await page.goto('./', { waitUntil: 'domcontentloaded' });
4042
await expect(page.getByText('Select Role')).toBeVisible();

e2e/tests/functional/plugins/operatorStatus/operatorStatus.e2e.spec.js

Lines changed: 141 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -33,146 +33,161 @@ Precondition: Inject Example User, Operator Status Plugins
3333
Verify that user 1 sees updates from user/role 2 (Not possible without openmct-yamcs implementation)
3434
3535
Clear Role Status of single user test
36-
STUB (test.fixme) Rolling through each
3736
3837
*/
3938

4039
test.describe('Operator Status', () => {
41-
test.beforeEach(async ({ page }) => {
42-
// FIXME: determine if plugins will be added to index.html or need to be injected
43-
await page.addInitScript({
44-
path: fileURLToPath(new URL('../../../../helper/addInitExampleUser.js', import.meta.url))
40+
test.describe('as user with status and poll permissions', () => {
41+
test.beforeEach(async ({ page }) => {
42+
await page.addInitScript({
43+
path: fileURLToPath(
44+
new URL('../../../../helper/addInitExampleUserMultipleRoles.js', import.meta.url)
45+
)
46+
});
47+
await page.addInitScript({
48+
path: fileURLToPath(new URL('../../../../helper/addInitOperatorStatus.js', import.meta.url))
49+
});
50+
await page.goto('./', { waitUntil: 'domcontentloaded' });
51+
await expect(page.getByText('Select Role')).toBeVisible();
52+
// Description should be empty https://github.com/nasa/openmct/issues/6978
53+
await expect(page.locator('.c-message__action-text')).toBeHidden();
54+
// set role
55+
await page.getByRole('button', { name: 'Select', exact: true }).click();
56+
// dismiss role confirmation popup
57+
await page.getByRole('button', { name: 'Dismiss' }).click();
4558
});
46-
await page.addInitScript({
47-
path: fileURLToPath(new URL('../../../../helper/addInitOperatorStatus.js', import.meta.url))
59+
60+
// verify that operator status is visible
61+
test('operator status is visible and expands when clicked', async ({ page }) => {
62+
await expect(page.locator('div[title="Set my operator status"]')).toBeVisible();
63+
await page.locator('div[title="Set my operator status"]').click();
64+
await expect(page.locator('.c-status-poll-panel')).toBeVisible();
4865
});
49-
await page.goto('./', { waitUntil: 'domcontentloaded' });
50-
await expect(page.getByText('Select Role')).toBeVisible();
51-
// Description should be empty https://github.com/nasa/openmct/issues/6978
52-
await expect(page.locator('.c-message__action-text')).toBeHidden();
53-
// set role
54-
await page.getByRole('button', { name: 'Select', exact: true }).click();
55-
// dismiss role confirmation popup
56-
await page.getByRole('button', { name: 'Dismiss' }).click();
57-
});
5866

59-
// verify that operator status is visible
60-
test('operator status is visible and expands when clicked', async ({ page }) => {
61-
await expect(page.locator('div[title="Set my operator status"]')).toBeVisible();
62-
await page.locator('div[title="Set my operator status"]').click();
67+
test('poll question indicator remains when blank poll set', async ({ page }) => {
68+
await expect(page.locator('div[title="Set the current poll question"]')).toBeVisible();
69+
await page.locator('div[title="Set the current poll question"]').click();
70+
// set to blank
71+
await page.getByRole('button', { name: 'Update' }).click();
6372

64-
// expect default status to be 'GO'
65-
await expect(page.locator('.c-status-poll-panel')).toBeVisible();
66-
});
73+
// should still be visible
74+
await expect(page.locator('div[title="Set the current poll question"]')).toBeVisible();
75+
});
6776

68-
test('poll question indicator remains when blank poll set', async ({ page }) => {
69-
await expect(page.locator('div[title="Set the current poll question"]')).toBeVisible();
70-
await page.locator('div[title="Set the current poll question"]').click();
71-
// set to blank
72-
await page.getByRole('button', { name: 'Update' }).click();
77+
// Verify that user 1 sees updates from user/role 2 (Not possible without openmct-yamcs implementation)
78+
test('operator status table reflects answered values', async ({ page }) => {
79+
// user navigates to operator status poll
80+
const statusPollIndicator = page.locator('div[title="Set my operator status"]');
81+
await statusPollIndicator.click();
82+
83+
// get user role value
84+
const userRole = page.locator('.c-status-poll-panel__user-role');
85+
const userRoleText = await userRole.innerText();
86+
87+
// get selected status value
88+
const selectStatus = page.locator('select[name="setStatus"]');
89+
await selectStatus.selectOption({ index: 1 });
90+
const initialStatusValue = await selectStatus.inputValue();
91+
92+
// open manage status poll
93+
const manageStatusPollIndicator = page.locator('div[title="Set the current poll question"]');
94+
await manageStatusPollIndicator.click();
95+
// parse the table row values
96+
const row = page.locator(`tr:has-text("${userRoleText}")`);
97+
const rowValues = await row.innerText();
98+
const rowValuesArr = rowValues.split('\t');
99+
const COLUMN_STATUS_INDEX = 1;
100+
// check initial set value matches status table
101+
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
102+
initialStatusValue.toLowerCase()
103+
);
104+
105+
// change user status
106+
await statusPollIndicator.click();
107+
// FIXME: might want to grab a dynamic option instead of arbitrary
108+
await page.locator('select[name="setStatus"]').selectOption({ index: 2 });
109+
const updatedStatusValue = await selectStatus.inputValue();
110+
// verify user status is reflected in table
111+
await manageStatusPollIndicator.click();
112+
113+
const updatedRow = page.locator(`tr:has-text("${userRoleText}")`);
114+
const updatedRowValues = await updatedRow.innerText();
115+
const updatedRowValuesArr = updatedRowValues.split('\t');
116+
117+
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
118+
updatedStatusValue.toLowerCase()
119+
);
120+
});
73121

74-
// should still be visible
75-
await expect(page.locator('div[title="Set the current poll question"]')).toBeVisible();
76-
});
122+
test('clear poll button removes poll responses', async ({ page }) => {
123+
// user navigates to operator status poll
124+
const statusPollIndicator = page.locator('div[title="Set my operator status"]');
125+
await statusPollIndicator.click();
126+
127+
// get user role value
128+
const userRole = page.locator('.c-status-poll-panel__user-role');
129+
const userRoleText = await userRole.innerText();
130+
131+
// get selected status value
132+
const selectStatus = page.locator('select[name="setStatus"]');
133+
// FIXME: might want to grab a dynamic option instead of arbitrary
134+
await selectStatus.selectOption({ index: 1 });
135+
const initialStatusValue = await selectStatus.inputValue();
136+
137+
// open manage status poll
138+
const manageStatusPollIndicator = page.locator('div[title="Set the current poll question"]');
139+
await manageStatusPollIndicator.click();
140+
// parse the table row values
141+
const row = page.locator(`tr:has-text("${userRoleText}")`);
142+
const rowValues = await row.innerText();
143+
const rowValuesArr = rowValues.split('\t');
144+
const COLUMN_STATUS_INDEX = 1;
145+
// check initial set value matches status table
146+
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
147+
initialStatusValue.toLowerCase()
148+
);
149+
150+
// clear the poll
151+
await page.locator('button[title="Clear the previous poll question"]').click();
152+
153+
const updatedRow = page.locator('tr').filter({ hasText: userRoleText });
154+
155+
await expect(updatedRow).toContainText('Not set');
156+
});
77157

78-
// Verify that user 1 sees updates from user/role 2 (Not possible without openmct-yamcs implementation)
79-
test('operator status table reflects answered values', async ({ page }) => {
80-
// user navigates to operator status poll
81-
const statusPollIndicator = page.locator('div[title="Set my operator status"]');
82-
await statusPollIndicator.click();
83-
84-
// get user role value
85-
const userRole = page.locator('.c-status-poll-panel__user-role');
86-
const userRoleText = await userRole.innerText();
87-
88-
// get selected status value
89-
const selectStatus = page.locator('select[name="setStatus"]');
90-
await selectStatus.selectOption({ index: 1 });
91-
const initialStatusValue = await selectStatus.inputValue();
92-
93-
// open manage status poll
94-
const manageStatusPollIndicator = page.locator('div[title="Set the current poll question"]');
95-
await manageStatusPollIndicator.click();
96-
// parse the table row values
97-
const row = page.locator(`tr:has-text("${userRoleText}")`);
98-
const rowValues = await row.innerText();
99-
const rowValuesArr = rowValues.split('\t');
100-
const COLUMN_STATUS_INDEX = 1;
101-
// check initial set value matches status table
102-
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
103-
initialStatusValue.toLowerCase()
104-
);
105-
106-
// change user status
107-
await statusPollIndicator.click();
108-
// FIXME: might want to grab a dynamic option instead of arbitrary
109-
await page.locator('select[name="setStatus"]').selectOption({ index: 2 });
110-
const updatedStatusValue = await selectStatus.inputValue();
111-
// verify user status is reflected in table
112-
await manageStatusPollIndicator.click();
113-
114-
const updatedRow = page.locator(`tr:has-text("${userRoleText}")`);
115-
const updatedRowValues = await updatedRow.innerText();
116-
const updatedRowValuesArr = updatedRowValues.split('\t');
117-
118-
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
119-
updatedStatusValue.toLowerCase()
120-
);
121-
});
158+
test('Poll indicator is visible when window is really small', async ({ page }) => {
159+
const pollIndicator = page.locator('div[title="Set my operator status"]');
160+
//Make window narrow
161+
await page.setViewportSize({ width: 640, height: 480 });
162+
await page.getByLabel('Display as single line').click();
163+
const indicatorsCount = await page.locator('.c-indicator').count();
164+
//Assert that multiple indicators are active
165+
expect(indicatorsCount).toBeGreaterThanOrEqual(3);
166+
//Assert that indicators are expanded
167+
await expect(page.locator('.l-shell__head')).toContainClass('l-shell__head--expanded');
168+
//Expect poll indicator to be visible
169+
await expect(pollIndicator).toBeInViewport({ ratio: 1 });
170+
});
122171

123-
test('clear poll button removes poll responses', async ({ page }) => {
124-
// user navigates to operator status poll
125-
const statusPollIndicator = page.locator('div[title="Set my operator status"]');
126-
await statusPollIndicator.click();
127-
128-
// get user role value
129-
const userRole = page.locator('.c-status-poll-panel__user-role');
130-
const userRoleText = await userRole.innerText();
131-
132-
// get selected status value
133-
const selectStatus = page.locator('select[name="setStatus"]');
134-
// FIXME: might want to grab a dynamic option instead of arbitrary
135-
await selectStatus.selectOption({ index: 1 });
136-
const initialStatusValue = await selectStatus.inputValue();
137-
138-
// open manage status poll
139-
const manageStatusPollIndicator = page.locator('div[title="Set the current poll question"]');
140-
await manageStatusPollIndicator.click();
141-
// parse the table row values
142-
const row = page.locator(`tr:has-text("${userRoleText}")`);
143-
const rowValues = await row.innerText();
144-
const rowValuesArr = rowValues.split('\t');
145-
const COLUMN_STATUS_INDEX = 1;
146-
// check initial set value matches status table
147-
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
148-
initialStatusValue.toLowerCase()
149-
);
150-
151-
// clear the poll
152-
await page.locator('button[title="Clear the previous poll question"]').click();
153-
154-
const updatedRow = page.locator(`tr:has-text("${userRoleText}")`);
155-
const updatedRowValues = await updatedRow.innerText();
156-
const updatedRowValuesArr = updatedRowValues.split('\t');
157-
const UNSET_VALUE_LABEL = 'Not set';
158-
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX]).toEqual(UNSET_VALUE_LABEL);
172+
test.fixme('iterate through all possible response values', async ({ page }) => {
173+
// test all possible response values for the poll
174+
});
159175
});
160176

161-
test('Poll indicator is visible when window is really small', async ({ page }) => {
162-
const pollIndicator = page.locator('div[title="Set my operator status"]');
163-
//Make window narrow
164-
await page.setViewportSize({ width: 640, height: 480 });
165-
await page.getByLabel('Display as single line').click();
166-
const indicatorsCount = await page.locator('.c-indicator').count();
167-
//Assert that multiple indicators are active
168-
expect(indicatorsCount).toBeGreaterThanOrEqual(3);
169-
//Assert that indicators are expanded
170-
await expect(page.locator('.l-shell__head')).toContainClass('l-shell__head--expanded');
171-
//Expect poll indicator to be visible
172-
await expect(pollIndicator).toBeInViewport({ ratio: 1 });
173-
});
177+
test.describe('as user without status permissions', () => {
178+
test.beforeEach(async ({ page }) => {
179+
await page.addInitScript({
180+
path: fileURLToPath(new URL('../../../../helper/addInitExampleUser.js', import.meta.url))
181+
});
182+
await page.addInitScript({
183+
path: fileURLToPath(new URL('../../../../helper/addInitOperatorStatus.js', import.meta.url))
184+
});
185+
await page.goto('./', { waitUntil: 'domcontentloaded' });
186+
});
174187

175-
test.fixme('iterate through all possible response values', async ({ page }) => {
176-
// test all possible response values for the poll
188+
// verify that operator status is visible
189+
test('operator status is not visible', async ({ page }) => {
190+
await expect(page.locator('div[title="Set my operator status"]')).toBeHidden();
191+
});
177192
});
178193
});

e2e/tests/functional/userRoles.e2e.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import { expect, test } from '../../pluginFixtures.js';
2727
test.describe('User Roles', () => {
2828
test('Role prompting', async ({ page }) => {
2929
await page.addInitScript({
30-
path: fileURLToPath(new URL('../../helper/addInitExampleUser.js', import.meta.url))
30+
path: fileURLToPath(
31+
new URL('../../helper/addInitExampleUserMultipleRoles.js', import.meta.url)
32+
)
3133
});
3234
await page.goto('./', { waitUntil: 'domcontentloaded' });
3335

e2e/tests/visual-a11y/components/header.visual.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ test.describe('Visual - Header @a11y', () => {
9797
test.describe('Mission Header @a11y', () => {
9898
test.beforeEach(async ({ page }) => {
9999
await page.addInitScript({
100-
path: fileURLToPath(new URL('../../../helper/addInitExampleUser.js', import.meta.url))
100+
path: fileURLToPath(
101+
new URL('../../../helper/addInitExampleUserMultipleRoles.js', import.meta.url)
102+
)
101103
});
102104
await page.goto('./', { waitUntil: 'domcontentloaded' });
103105
await expect(page.getByText('Select Role')).toBeVisible();

e2e/tests/visual-a11y/missionStatus.visual.spec.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ test.describe('Mission Status Visual Tests @a11y', () => {
2828
const GO = '1';
2929
test.beforeEach(async ({ page }) => {
3030
await page.addInitScript({
31-
path: fileURLToPath(new URL('../../helper/addInitExampleUser.js', import.meta.url))
31+
path: fileURLToPath(
32+
new URL('../../helper/addInitExampleUserMultipleRoles.js', import.meta.url)
33+
)
3234
});
3335
await page.goto('./', { waitUntil: 'domcontentloaded' });
3436
await expect(page.getByText('Select Role')).toBeVisible();

0 commit comments

Comments
 (0)