Compare commits
	
		
			6 Commits
		
	
	
		
			release/2.
			...
			coverage-f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 18137fe125 | ||
|   | 51a6ff7825 | ||
|   | f989733e81 | ||
|   | 5a6162eb4c | ||
|   | b0a2f8dd8b | ||
|   | 54bed23267 | 
							
								
								
									
										1
									
								
								e2e/localstorage.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								e2e/localstorage.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"tcHistory":"{\"utc\":[{\"start\":1640401741152,\"end\":1640403541152}]}","mct":"{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"persisted\":1640403542253,\"modified\":1640403542253},\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\":{\"identifier\":{\"key\":\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\",\"namespace\":\"\"},\"name\":\"All DomainObjects\",\"type\":\"folder\",\"composition\":[{\"key\":\"cbee96e6-ec97-4059-a5bb-5a81b834ff3d\",\"namespace\":\"\"},{\"key\":\"15631105-127c-44a0-8d54-e3800943a98b\",\"namespace\":\"\"},{\"key\":\"31c2c6e1-55bd-4339-86f9-8cb1693566d0\",\"namespace\":\"\"}],\"modified\":1640403603547,\"location\":\"mine\",\"persisted\":1640403603547},\"cbee96e6-ec97-4059-a5bb-5a81b834ff3d\":{\"identifier\":{\"key\":\"cbee96e6-ec97-4059-a5bb-5a81b834ff3d\",\"namespace\":\"\"},\"name\":\"Unnamed Timer\",\"type\":\"timer\",\"configuration\":{\"timerFormat\":\"long\",\"timezone\":\"UTC\",\"timerState\":\"stopped\"},\"modified\":1640403543115,\"location\":\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\",\"persisted\":1640403543115},\"15631105-127c-44a0-8d54-e3800943a98b\":{\"identifier\":{\"key\":\"15631105-127c-44a0-8d54-e3800943a98b\",\"namespace\":\"\"},\"name\":\"Notebook\",\"type\":\"notebook\",\"configuration\":{\"defaultSort\":\"oldest\",\"entries\":{},\"imageMigrationVer\":\"v1\",\"pageTitle\":\"Page\",\"sections\":[{\"id\":\"ef4092ba-b6d1-4275-a659-bfae80b6ec9a\",\"isDefault\":false,\"isSelected\":true,\"name\":\"Unnamed Section\",\"pages\":[{\"id\":\"b187e90c-4759-47d5-af16-4a347520c0a6\",\"isDefault\":false,\"isSelected\":true,\"name\":\"Unnamed Page\",\"pageTitle\":\"Page\"}],\"sectionTitle\":\"Section\"}],\"sectionTitle\":\"Section\",\"type\":\"General\"},\"modified\":1640403544367,\"location\":\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\",\"persisted\":1640403544368},\"31c2c6e1-55bd-4339-86f9-8cb1693566d0\":{\"name\":\"Mega Display Layout\",\"type\":\"layout\",\"identifier\":{\"key\":\"31c2c6e1-55bd-4339-86f9-8cb1693566d0\",\"namespace\":\"\"},\"composition\":[],\"configuration\":{\"items\":[],\"layoutGrid\":[10,10]},\"modified\":1640403603545,\"location\":\"fbb74cd3-bc17-4913-a47b-6ec7b620c26d\",\"persisted\":1640403603545}}","mct-tree-expanded":"[]"} | ||||
| @@ -5,7 +5,7 @@ | ||||
| /** @type {import('@playwright/test').PlaywrightTestConfig} */ | ||||
| const config = { | ||||
|     retries: 0, | ||||
|     testDir: 'tests', | ||||
|     testDir: 'tests/visual', | ||||
|     timeout: 90 * 1000, | ||||
|     workers: 1, | ||||
|     webServer: { | ||||
| @@ -26,7 +26,6 @@ const config = { | ||||
|     reporter: [ | ||||
|         ['list'], | ||||
|         ['junit', { outputFile: 'test-results/results.xml' }], | ||||
|         ['allure-playwright'] | ||||
|     ] | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										122
									
								
								e2e/tests/generateLocalStorage.e2e.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								e2e/tests/generateLocalStorage.e2e.spec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /* | ||||
| This test suite is used for generating localStorage artifacts for visual and performance | ||||
| tests. This must be generated against app.js | ||||
| */ | ||||
|  | ||||
| const { test, expect } = require('@playwright/test'); | ||||
| const fs = require('fs'); | ||||
|  | ||||
| test('Generate domainObjects and store localstorage as localstorage.json', async ({ page }) => { | ||||
|  | ||||
|     //Go to baseURL | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|     //Click the Create button | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click :nth-match(:text("Folder"), 2) | ||||
|     await page.click(':nth-match(:text("Folder"), 2)'); | ||||
|  | ||||
|     // Fill text=Properties Title Notes >> input[type="text"] | ||||
|     await page.fill('text=Properties Title Notes >> input[type="text"]', 'All DomainObjects'); | ||||
|     //await page.fill('input[type="text"]', 'All DomainObjects'); | ||||
|  | ||||
|     // Click text=OK | ||||
|     await Promise.all([ | ||||
|         page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/mine/07fa1bd8-1e7d-4b74-bc40-f561f8c00535?tc.mode=fixed&tc.startBound=1640392618958&tc.endBound=1640394418958&tc.timeSystem=utc&view=grid' }*/), | ||||
|         page.click('text=OK') | ||||
|     ]); | ||||
|  | ||||
|     // Click button:has-text("Create") | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click text=Timer | ||||
|     await page.click('text=Timer'); | ||||
|  | ||||
|     // Click text=Save In My Items All DomainObjects >> input[type="search"] | ||||
|     await page.click('text=Save In My Items All DomainObjects >> input[type="search"]'); | ||||
|  | ||||
|     // Fill text=Save In My Items All DomainObjects >> input[type="search"] | ||||
|     await page.fill('text=Save In My Items All DomainObjects >> input[type="search"]', 'All DomainObjects'); | ||||
|  | ||||
|     // Click text=OK | ||||
|     await Promise.all([ | ||||
|         page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/mine/07fa1bd8-1e7d-4b74-bc40-f561f8c00535/810cc308-76d6-4e64-ab85-cb543c655698?tc.mode=fixed&tc.startBound=1640392618958&tc.endBound=1640394418958&tc.timeSystem=utc&view=timer.view' }*/), | ||||
|         page.click('text=OK') | ||||
|     ]); | ||||
|  | ||||
|     // Click button:has-text("Create") | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click text=Notebook | ||||
|     await page.click('text=Notebook'); | ||||
|  | ||||
|     // Fill text=Properties Title Notes Entry Sorting Newest First Oldest First Note book Type Se >> input[type="text"] | ||||
|     await page.fill('text=Properties Title Notes Entry Sorting Newest First Oldest First Note book Type Se >> input[type="text"]', 'Notebook'); | ||||
|  | ||||
|     // Click text=Save In My Items All DomainObjects Unnamed Timer >> input[type="search"] | ||||
|     //await page.click('text=Save In My Items All DomainObjects Unnamed Timer >> input[type="search"]'); | ||||
|  | ||||
|     // Fill text=Save In My Items All DomainObjects Unnamed Timer >> input[type="search"] | ||||
|     await page.fill('text=Save In My Items All DomainObjects Unnamed Timer >> input[type="search"]', 'All DomainObjects'); | ||||
|  | ||||
|     // Click ul:nth-child(3) .c-tree__item-h .c-tree__item | ||||
|     await page.click('ul:nth-child(3) .c-tree__item-h .c-tree__item'); | ||||
|  | ||||
|     // Click button:has-text("OK") | ||||
|     await Promise.all([ | ||||
|         page.waitForNavigation(/*{ url: 'http://localhost:8080/#/browse/ROOT/mine/07fa1bd8-1e7d-4b74-bc40-f561f8c00535/6b10425e-2d7f-4f65-83de-35317fbc2493?tc.mode=fixed&tc.startBound=1640392618958&tc.endBound=1640394418958&tc.timeSystem=utc&view=notebook-vue&pageId=9ad5b4ea-8dec-4cc0-b303-43a4f50ac7fa§ionId=d298175b-d715-426e-8036-b87056e14525' }*/), | ||||
|         page.click('button:has-text("OK")') | ||||
|     ]); | ||||
|  | ||||
|     await page.pause(); | ||||
|  | ||||
|     const localStorage = await page.evaluate(() => JSON.stringify(window.localStorage)); | ||||
|     fs.writeFileSync('e2e/localstorage.json', localStorage); | ||||
| }); | ||||
|  | ||||
| test('Load localstorage.json and verify contents', async ({ page }) => { | ||||
|  | ||||
|     //Go to baseURL | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|     const localStorage = fs.readFileSync('e2e/localstorage.json', 'utf8') | ||||
|  | ||||
|     const deserializedStorage = JSON.parse(localStorage) | ||||
|     await page.evaluate(deserializedStorage => { | ||||
|         for (const key in deserializedStorage) { | ||||
|             localStorage.setItem(key, deserializedStorage[key]); | ||||
|         } | ||||
|     }, deserializedStorage); | ||||
|  | ||||
|     await page.reload(); | ||||
|      | ||||
|     // Expand Default Folder | ||||
|     await page.click('a:has-text("All DomainObjects Folder")'); | ||||
|  | ||||
|     await expect(page.locator('a:has-text("Unnamed Timer Timer")')).toBeEnabled(); | ||||
|     await expect(page.locator('a:has-text("Notebook Notebook")')).toBeEnabled(); | ||||
|  | ||||
| }); | ||||
| @@ -44,6 +44,5 @@ test('Verify that the create button appears and that the Folder Domain Object is | ||||
|     await page.click('button:has-text("Create")'); | ||||
| 
 | ||||
|     // Verify that Create Folder appears in the dropdown
 | ||||
|     const locator = page.locator(':nth-match(:text("Folder"), 2)'); | ||||
|     await expect(locator).toBeEnabled(); | ||||
|     await expect(page.locator(':nth-match(:text("Folder"), 2)')).toBeEnabled(); | ||||
| }); | ||||
| @@ -36,12 +36,13 @@ const { test, expect } = require('@playwright/test'); | ||||
| const percySnapshot = require('@percy/playwright'); | ||||
| const path = require('path'); | ||||
| const sinon = require('sinon'); | ||||
| const fs = require('fs'); | ||||
| 
 | ||||
| const VISUAL_GRACE_PERIOD = 5 * 1000; //Lets the application "simmer" before the snapshot is taken
 | ||||
| const VISUAL_GRACE_PERIOD = 1 * 1000; //Lets the application "simmer" before the snapshot is taken
 | ||||
| 
 | ||||
| // Snippet from https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
 | ||||
| // Will replace with cy.clock() equivalent
 | ||||
| test.beforeEach(async ({ context }) => { | ||||
| test.beforeEach(async ({ context,page }) => { | ||||
|     await context.addInitScript({ | ||||
|         // eslint-disable-next-line no-undef
 | ||||
|         path: path.join(__dirname, '../../..', './node_modules/sinon/pkg/sinon.js') | ||||
| @@ -49,11 +50,10 @@ test.beforeEach(async ({ context }) => { | ||||
|     await context.addInitScript(() => { | ||||
|         window.__clock = sinon.useFakeTimers(); //Set browser clock to UNIX Epoch
 | ||||
|     }); | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
| }); | ||||
| 
 | ||||
| test('Visual - Root and About', async ({ page }) => { | ||||
|     // Go to baseURL
 | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
| 
 | ||||
|     // Verify that Create button is actionable
 | ||||
|     const createButtonLocator = page.locator('button:has-text("Create")'); | ||||
| @@ -77,8 +77,6 @@ test('Visual - Root and About', async ({ page }) => { | ||||
| }); | ||||
| 
 | ||||
| test('Visual - Default Condition Set', async ({ page }) => { | ||||
|     //Go to baseURL
 | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
| 
 | ||||
|     //Click the Create button
 | ||||
|     await page.click('button:has-text("Create")'); | ||||
| @@ -95,8 +93,6 @@ test('Visual - Default Condition Set', async ({ page }) => { | ||||
| }); | ||||
| 
 | ||||
| test('Visual - Default Condition Widget', async ({ page }) => { | ||||
|     //Go to baseURL
 | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
| 
 | ||||
|     //Click the Create button
 | ||||
|     await page.click('button:has-text("Create")'); | ||||
| @@ -111,3 +107,35 @@ test('Visual - Default Condition Widget', async ({ page }) => { | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Condition Widget'); | ||||
| }); | ||||
| 
 | ||||
| test('Visual - Default Timer', async ({ page }) => { | ||||
| 
 | ||||
|     //Click the Create button
 | ||||
|     await page.click('button:has-text("Create")'); | ||||
| 
 | ||||
|     // Click text=Timer
 | ||||
|     await page.click('text=Timer'); | ||||
| 
 | ||||
|     // Click text=OK
 | ||||
|     await page.click('text=OK'); | ||||
| 
 | ||||
|     // Take a snapshot of the newly created Condition Widget object
 | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Timer'); | ||||
| }); | ||||
| 
 | ||||
| test('Visual - Default Display Layout', async ({ page }) => { | ||||
| 
 | ||||
|     //Click the Create button
 | ||||
|     await page.click('button:has-text("Create")'); | ||||
| 
 | ||||
|     // Click text=Timer
 | ||||
|     await page.click('text=Display Layout'); | ||||
| 
 | ||||
|     // Click text=OK
 | ||||
|     await page.click('text=OK'); | ||||
| 
 | ||||
|     // Take a snapshot of the newly created Condition Widget object
 | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Display Layout'); | ||||
| }); | ||||
							
								
								
									
										82
									
								
								e2e/tests/visual/localStorage.visual.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								e2e/tests/visual/localStorage.visual.spec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /* | ||||
| Collection of Visual Tests set to run from a pre-generated . The tests within this suite | ||||
| are only meant to run against openmct's app.js started by `npm run start` within the  | ||||
| `./e2e/playwright-visual.config.js` file. | ||||
|  | ||||
| These should only use functional expect statements to verify assumptions about the state  | ||||
| in a test and not for functional verification of correctness. Visual tests are not supposed | ||||
| to "fail" on assertions. Instead, they should be used to detect changes between builds or branches. | ||||
|  | ||||
| Note: Larger testsuite sizes are OK due to the setup time associated with these tests.  | ||||
| */ | ||||
|  | ||||
| const { test, expect } = require('@playwright/test'); | ||||
| const percySnapshot = require('@percy/playwright'); | ||||
| const path = require('path'); | ||||
| const sinon = require('sinon'); | ||||
| const fs = require('fs'); | ||||
|  | ||||
| const VISUAL_GRACE_PERIOD = 1 * 1000; //Lets the application "simmer" before the snapshot is taken | ||||
|  | ||||
| // Snippet from https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758 | ||||
| // Will replace with cy.clock() equivalent | ||||
| test.beforeEach(async ({ context,page }) => { | ||||
|     await context.addInitScript({ | ||||
|         // eslint-disable-next-line no-undef | ||||
|         path: path.join(__dirname, '../../..', './node_modules/sinon/pkg/sinon.js') | ||||
|     }); | ||||
|     await context.addInitScript(() => { | ||||
|         window.__clock = sinon.useFakeTimers(); //Set browser clock to UNIX Epoch | ||||
|     }); | ||||
|  | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|     const localStorage = fs.readFileSync('e2e/localstorage.json', 'utf8') | ||||
|  | ||||
|     const deserializedStorage = JSON.parse(localStorage) | ||||
|     await page.evaluate(deserializedStorage => { | ||||
|         for (const key in deserializedStorage) { | ||||
|             localStorage.setItem(key, deserializedStorage[key]); | ||||
|         } | ||||
|     }, deserializedStorage); | ||||
|  | ||||
|     await page.reload(); | ||||
| }); | ||||
|  | ||||
| test('Visual - Combined Display Layout', async ({ page }) => { | ||||
|  | ||||
|     //Click the Create button | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click text=Timer | ||||
|     await page.click('text=Display Layout'); | ||||
|  | ||||
|     // Click text=OK | ||||
|     await page.click('text=OK'); | ||||
|  | ||||
|     // Take a snapshot of the newly created Condition Widget object | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Display Layout'); | ||||
| }); | ||||
| @@ -6,7 +6,7 @@ | ||||
|     "@braintree/sanitize-url": "^5.0.2", | ||||
|     "@percy/cli": "^1.0.0-beta.70", | ||||
|     "@percy/playwright": "^1.0.1", | ||||
|     "@playwright/test": "^1.16.3", | ||||
|     "@playwright/test": "^1.17.1", | ||||
|     "allure-playwright": "^2.0.0-beta.14", | ||||
|     "angular": ">=1.8.0", | ||||
|     "angular-route": "1.4.14", | ||||
| @@ -58,7 +58,7 @@ | ||||
|     "moment-timezone": "0.5.28", | ||||
|     "node-bourbon": "^4.2.3", | ||||
|     "painterro": "^1.2.56", | ||||
|     "playwright": "^1.16.3", | ||||
|     "playwright": "^1.17.1", | ||||
|     "plotly.js-basic-dist": "^2.5.0", | ||||
|     "plotly.js-gl2d-dist": "^2.5.0", | ||||
|     "printj": "^1.2.1", | ||||
| @@ -97,8 +97,9 @@ | ||||
|     "test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run", | ||||
|     "test:coverage:firefox": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run --browsers=FirefoxHeadless", | ||||
|     "test:e2e:ci": "npx playwright test --config=e2e/playwright-ci.config.js smoke", | ||||
|     "test:e2e:generate": "npx playwright test --config=e2e/playwright-local.config.js generateLocalStorage", | ||||
|     "test:e2e:local": "npx playwright test --config=e2e/playwright-local.config.js", | ||||
|     "test:e2e:visual": "percy exec -- npx playwright test --config=e2e/playwright-visual.config.js default", | ||||
|     "test:e2e:visual": "percy exec -- npx playwright test --config=e2e/playwright-visual.config.js", | ||||
|     "test:e2e:full": "npx playwright test --config=e2e/playwright-ci.config.js", | ||||
|     "test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run", | ||||
|     "verify": "concurrently 'npm:test' 'npm:lint'", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user