Compare commits
	
		
			14 Commits
		
	
	
		
			couchdb-ci
			...
			reorder-in
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e83d20da3a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 47fb81ff1c | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 0efc6987a5 | ||
|   | 79d1df39b7 | ||
|   | 0c9ea26888 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 153538b6bf | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 798e2d4337 | ||
|   | e3770dc701 | ||
|   | 0f12aa1eae | ||
|   | b786fbb799 | ||
|   | 2bbfd7fd33 | ||
|   | f36b2ba3f7 | ||
|   | c6e147a563 | ||
|   | a890b3d9b0 | 
							
								
								
									
										5
									
								
								.github/workflows/e2e-couchdb.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/e2e-couchdb.yml
									
									
									
									
										vendored
									
									
								
							| @@ -17,8 +17,9 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - run : docker-compose up -d -f src/plugins/persistence/couch/couchdb-compose.yaml | ||||
|       - run : sh src/plugins/persistence/couch/setup-couchdb.sh | ||||
|       - run : docker-compose -f src/plugins/persistence/couch/couchdb-compose.yaml up --detach | ||||
|       - run : sleep 3 # wait until CouchDB has started (TODO: there must be a better way) | ||||
|       - run : bash src/plugins/persistence/couch/setup-couchdb.sh | ||||
|       - uses: actions/setup-node@v3 | ||||
|         with: | ||||
|           node-version: '16' | ||||
|   | ||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -36,6 +36,10 @@ report.*.json | ||||
| test-results | ||||
| html-test-results | ||||
|  | ||||
| # couchdb scripting artifacts | ||||
| src/plugins/persistence/couch/.env.local | ||||
| index.html.bak | ||||
|  | ||||
| # codecov artifacts | ||||
| .nyc_output | ||||
| coverage | ||||
|   | ||||
| @@ -23,21 +23,23 @@ If this is your first time ever using the Playwright framework, we recommend goi | ||||
| Once you've got an understanding of Playwright, you'll need a baseline understanding of Open MCT: | ||||
|  | ||||
| 1. Follow the steps [Building and Running Open MCT Locally](../README.md#building-and-running-open-mct-locally) | ||||
| 2. Once you're serving Open MCT locally, create an Example Telemetry Object (e.g.: 'Sine Wave Generator') | ||||
| 2. Once you're serving Open MCT locally, create a 'Display Layout' object. Save it. | ||||
| 3. Create a 'Plot' Object (e.g.: 'Stacked Plot') | ||||
| 4. Expand the Tree on the left-hand nav and drag and drop the Example Telemetry Object into the Plot Object | ||||
| 5. Create a 'Display Layout' object | ||||
| 6. From the Tree, Drag the Plot object into the Display Layout | ||||
| 4. Create an Example Telemetry Object (e.g.: 'Sine Wave Generator') | ||||
| 5. Expand the Tree and note the hierarchy of objects which were created. | ||||
| 6. Navigate to the Demo Display Layout Object to edit and modify the embedded plot. | ||||
| 7. Modify the embedded plot with Telemetry Data. | ||||
|  | ||||
| What you've created is a display which mimics the display that a mission control operator might use to understand and model telemetry data. | ||||
|  | ||||
| Recreate the steps above with Playwright's codegen tool: | ||||
|  | ||||
| 1. `npm run start` in a terminal window | ||||
| 2. Open another terminal window and start the Playwright codegen application `npx playwright codegen` | ||||
| 3. Navigate the browser to `http://localhost:8080` | ||||
| 4. Click the Create button and notice how your actions in the browser are being recorded in the Playwright Inspector | ||||
| 5. Continue through the steps 2-6 above | ||||
| 1. `npm run start` in a terminal window to serve Open MCT locally | ||||
| 2. `npx @playwright/test install` to install playwright and dependencies | ||||
| 3. Open another terminal window and start the Playwright codegen application `npx playwright codegen` | ||||
| 4. Navigate the browser to `http://localhost:8080` | ||||
| 5. Click the Create button and notice how your actions in the browser are being recorded in the Playwright Inspector | ||||
| 6. Continue through the steps 2-6 above | ||||
|  | ||||
| What you've created is an automated test which mimics the creation of a mission control display. | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,7 @@ This test suite is dedicated to tests which verify the basic operations surround | ||||
| // FIXME: Remove this eslint exception once tests are implemented | ||||
| // eslint-disable-next-line no-unused-vars | ||||
| const { test, expect } = require('../../../../baseFixtures'); | ||||
| const { createDomainObjectWithDefaults } = require('../../../../appActions'); | ||||
|  | ||||
| test.describe('Notebook CRUD Operations', () => { | ||||
|     test.fixme('Can create a Notebook Object', async ({ page }) => { | ||||
| @@ -67,10 +68,32 @@ test.describe('Default Notebook', () => { | ||||
|  | ||||
| test.describe('Notebook section tests', () => { | ||||
|     //The following test cases are associated with Notebook Sections | ||||
|     test.fixme('New sections are automatically named Unnamed Section with Unnamed Page', async ({ page }) => { | ||||
|         //Create new notebook A | ||||
|         //Add section | ||||
|         //Verify new section and new page details | ||||
|     test.beforeEach(async ({ page }) => { | ||||
|         //Navigate to baseURL | ||||
|         await page.goto('./', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|         // Create Notebook | ||||
|         await createDomainObjectWithDefaults(page, { | ||||
|             type: 'Notebook', | ||||
|             name: "Test Notebook" | ||||
|         }); | ||||
|     }); | ||||
|     test('Default and new sections are automatically named Unnamed Section with Unnamed Page', async ({ page }) => { | ||||
|         // Check that the default section and page are created and the name matches the defaults | ||||
|         const defaultSectionName = await page.locator('.c-notebook__sections .c-list__item__name').textContent(); | ||||
|         expect(defaultSectionName).toBe('Unnamed Section'); | ||||
|         const defaultPageName = await page.locator('.c-notebook__pages .c-list__item__name').textContent(); | ||||
|         expect(defaultPageName).toBe('Unnamed Page'); | ||||
|  | ||||
|         // Expand sidebar and add a section | ||||
|         await page.locator('.c-notebook__toggle-nav-button').click(); | ||||
|         await page.locator('.js-sidebar-sections .c-icon-button.icon-plus').click(); | ||||
|  | ||||
|         // Check that new section and page within the new section match the defaults | ||||
|         const newSectionName = await page.locator('.c-notebook__sections .c-list__item__name').nth(1).textContent(); | ||||
|         expect(newSectionName).toBe('Unnamed Section'); | ||||
|         const newPageName = await page.locator('.c-notebook__pages .c-list__item__name').textContent(); | ||||
|         expect(newPageName).toBe('Unnamed Page'); | ||||
|     }); | ||||
|     test.fixme('Section selection operations and associated behavior', async ({ page }) => { | ||||
|         //Create new notebook A | ||||
| @@ -107,6 +130,38 @@ test.describe('Notebook section tests', () => { | ||||
|  | ||||
| test.describe('Notebook page tests', () => { | ||||
|     //The following test cases are associated with Notebook Pages | ||||
|     test.beforeEach(async ({ page }) => { | ||||
|         //Navigate to baseURL | ||||
|         await page.goto('./', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|         // Create Notebook | ||||
|         await createDomainObjectWithDefaults(page, { | ||||
|             type: 'Notebook', | ||||
|             name: "Test Notebook" | ||||
|         }); | ||||
|     }); | ||||
|     //Test will need to be implemented after a refactor in #5713 | ||||
|     // eslint-disable-next-line playwright/no-skipped-test | ||||
|     test.skip('Delete page popup is removed properly on clicking dropdown again', async ({ page }) => { | ||||
|         test.info().annotations.push({ | ||||
|             type: 'issue', | ||||
|             description: 'https://github.com/nasa/openmct/issues/5713' | ||||
|         }); | ||||
|         // Expand sidebar and add a second page | ||||
|         await page.locator('.c-notebook__toggle-nav-button').click(); | ||||
|         await page.locator('text=Page Add >> button').click(); | ||||
|  | ||||
|         // Click on the 2nd page dropdown button and expect the Delete Page option to appear | ||||
|         await page.locator('button[title="Open context menu"]').nth(2).click(); | ||||
|         await expect(page.locator('text=Delete Page')).toBeEnabled(); | ||||
|         // Clicking on the same page a second time causes the same Delete Page option to recreate | ||||
|         await page.locator('button[title="Open context menu"]').nth(2).click(); | ||||
|         await expect(page.locator('text=Delete Page')).toBeEnabled(); | ||||
|         // Clicking on the first page causes the first delete button to detach and recreate on the first page | ||||
|         await page.locator('button[title="Open context menu"]').nth(1).click(); | ||||
|         const numOfDeletePagePopups = await page.locator('li[title="Delete Page"]').count(); | ||||
|         expect(numOfDeletePagePopups).toBe(1); | ||||
|     }); | ||||
|     test.fixme('Page selection operations and associated behavior', async ({ page }) => { | ||||
|         //Create new notebook A | ||||
|         //Delete existing Page | ||||
|   | ||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ | ||||
|     "d3-axis": "3.0.0", | ||||
|     "d3-scale": "3.3.0", | ||||
|     "d3-selection": "3.0.0", | ||||
|     "eslint": "8.22.0", | ||||
|     "eslint": "8.23.0", | ||||
|     "eslint-plugin-compat": "4.0.2", | ||||
|     "eslint-plugin-playwright": "0.11.1", | ||||
|     "eslint-plugin-vue": "9.3.0", | ||||
| @@ -34,7 +34,7 @@ | ||||
|     "git-rev-sync": "3.0.2", | ||||
|     "html2canvas": "1.4.1", | ||||
|     "imports-loader": "4.0.1", | ||||
|     "jasmine-core": "4.3.0", | ||||
|     "jasmine-core": "4.4.0", | ||||
|     "karma": "6.3.20", | ||||
|     "karma-chrome-launcher": "3.1.1", | ||||
|     "karma-cli": "2.0.0", | ||||
| @@ -50,7 +50,7 @@ | ||||
|     "mini-css-extract-plugin": "2.6.1", | ||||
|     "moment": "2.29.4", | ||||
|     "moment-duration-format": "2.3.2", | ||||
|     "moment-timezone": "0.5.34", | ||||
|     "moment-timezone": "0.5.37", | ||||
|     "nyc":"15.1.0", | ||||
|     "painterro": "1.2.78", | ||||
|     "plotly.js-basic-dist": "2.14.0", | ||||
| @@ -62,7 +62,7 @@ | ||||
|     "sass-loader": "13.0.2", | ||||
|     "sinon": "14.0.0", | ||||
|     "style-loader": "^1.0.1", | ||||
|     "uuid": "8.3.2", | ||||
|     "uuid": "9.0.0", | ||||
|     "vue": "2.6.14", | ||||
|     "vue-eslint-parser": "9.0.2", | ||||
|     "vue-loader": "15.9.8", | ||||
| @@ -93,7 +93,7 @@ | ||||
|     "test:e2e:local": "npx playwright test --config=e2e/playwright-local.config.js --project=chrome", | ||||
|     "test:e2e:updatesnapshots": "npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep @snapshot --update-snapshots", | ||||
|     "test:e2e:visual": "percy exec --config ./e2e/.percy.yml -- npx playwright test --config=e2e/playwright-visual.config.js --grep-invert @unstable", | ||||
|     "test:e2e:full": "npx playwright test --config=e2e/playwright-ci.config.js", | ||||
|     "test:e2e:full": "npx playwright test --config=e2e/playwright-ci.config.js --grep-invert @couchdb", | ||||
|     "test:perf": "npx playwright test --config=e2e/playwright-performance.config.js", | ||||
|     "test:watch": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run", | ||||
|     "update-about-dialog-copyright": "perl -pi -e 's/20\\d\\d\\-202\\d/2014\\-2022/gm' ./src/ui/layout/AboutDialog.vue", | ||||
|   | ||||
| @@ -37,8 +37,8 @@ class IndicatorAPI extends EventEmitter { | ||||
|         return sortedIndicators; | ||||
|     } | ||||
|  | ||||
|     simpleIndicator() { | ||||
|         return new SimpleIndicator(this.openmct); | ||||
|     simpleIndicator(key) { | ||||
|         return new SimpleIndicator(this.openmct, key); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -63,6 +63,13 @@ class IndicatorAPI extends EventEmitter { | ||||
|      * | ||||
|      */ | ||||
|     add(indicator) { | ||||
|         const keyExists = indicator.key !== undefined | ||||
|             && this.indicatorObjects.some(installedIndicator => indicator.key === installedIndicator.key); | ||||
|  | ||||
|         if (keyExists) { | ||||
|             console.warn(`An Indicator with key { ${indicator.key} } has already been installed.`); | ||||
|         } | ||||
|  | ||||
|         if (!indicator.priority) { | ||||
|             indicator.priority = this.openmct.priority.DEFAULT; | ||||
|         } | ||||
| @@ -72,6 +79,22 @@ class IndicatorAPI extends EventEmitter { | ||||
|         this.emit('addIndicator', indicator); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {string} key the key of the indicator | ||||
|      * @param {number} priority the priority to set | ||||
|      */ | ||||
|     setPriority(key, priority) { | ||||
|         const indicatorToPrioritize = this.indicatorObjects | ||||
|             .find(indicator => indicator.key === key); | ||||
|  | ||||
|         if (indicatorToPrioritize !== undefined) { | ||||
|             indicatorToPrioritize.priority = priority; | ||||
|  | ||||
|             this.emit('setPriority', indicatorToPrioritize); | ||||
|         } else { | ||||
|             console.warn(`Could not find an installed indicator: ${key}`); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default IndicatorAPI; | ||||
|   | ||||
| @@ -22,6 +22,8 @@ | ||||
| import { createOpenMct, resetApplicationState } from '../../utils/testing'; | ||||
| import SimpleIndicator from './SimpleIndicator'; | ||||
|  | ||||
| const NOTIFICATIONS_INDICATOR_KEY = 'notifications-indicator'; | ||||
|  | ||||
| describe("The Indicator API", () => { | ||||
|     let openmct; | ||||
|  | ||||
| @@ -39,6 +41,7 @@ describe("The Indicator API", () => { | ||||
|         const textNode = document.createTextNode(label); | ||||
|         element.appendChild(textNode); | ||||
|         const testIndicator = { | ||||
|             key: className, | ||||
|             element, | ||||
|             priority | ||||
|         }; | ||||
| @@ -46,12 +49,22 @@ describe("The Indicator API", () => { | ||||
|         return testIndicator; | ||||
|     } | ||||
|  | ||||
|     it("installs the notifications indicator by default", () => { | ||||
|         let indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|         const notificationIndicator = indicators.find(indicator => indicator.key === NOTIFICATIONS_INDICATOR_KEY); | ||||
|  | ||||
|         expect(notificationIndicator.key).toEqual(NOTIFICATIONS_INDICATOR_KEY); | ||||
|     }); | ||||
|  | ||||
|     it("can register an indicator", () => { | ||||
|         let indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|         const defaultIndicatorsLength = indicators.length; | ||||
|         const testIndicator = generateIndicator('test-indicator', 'This is a test indicator', 2); | ||||
|  | ||||
|         openmct.indicators.add(testIndicator); | ||||
|         expect(openmct.indicators.indicatorObjects).toBeDefined(); | ||||
|         // notifier indicator is installed by default | ||||
|         expect(openmct.indicators.indicatorObjects.length).toBe(2); | ||||
|         indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|  | ||||
|         expect(indicators.length).toBe(defaultIndicatorsLength + 1); | ||||
|     }); | ||||
|  | ||||
|     it("can order indicators based on priority", () => { | ||||
| @@ -67,10 +80,32 @@ describe("The Indicator API", () => { | ||||
|         const testIndicator4 = generateIndicator('test-indicator-4', 'This is yet another test indicator', openmct.priority.HIGH); | ||||
|         openmct.indicators.add(testIndicator4); | ||||
|  | ||||
|         expect(openmct.indicators.indicatorObjects.length).toBe(5); | ||||
|         const indicatorObjectsByPriority = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|         expect(indicatorObjectsByPriority.length).toBe(5); | ||||
|         expect(indicatorObjectsByPriority[2].priority).toBe(openmct.priority.DEFAULT); | ||||
|         let indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|  | ||||
|         expect(indicators.length).toBe(5); | ||||
|         expect(indicators[2].priority).toBe(openmct.priority.DEFAULT); | ||||
|     }); | ||||
|  | ||||
|     it("can change priority of an installed indicator", () => { | ||||
|         const testIndicator1 = generateIndicator('test-indicator-1', 'This is a test indicator', openmct.priority.LOW); | ||||
|         openmct.indicators.add(testIndicator1); | ||||
|  | ||||
|         const testIndicator2 = generateIndicator('test-indicator-2', 'This is another test indicator', openmct.priority.DEFAULT); | ||||
|         openmct.indicators.add(testIndicator2); | ||||
|  | ||||
|         const testIndicator3 = generateIndicator('test-indicator-3', 'This is yet another test indicator', openmct.priority.LOW); | ||||
|         openmct.indicators.add(testIndicator3); | ||||
|  | ||||
|         const testIndicator4 = generateIndicator('test-indicator-4', 'This is yet another test indicator', openmct.priority.HIGH); | ||||
|         openmct.indicators.add(testIndicator4); | ||||
|  | ||||
|         let indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|  | ||||
|         expect(indicators[0].key).toEqual('test-indicator-4'); | ||||
|         openmct.indicators.setPriority('test-indicator-2', openmct.priority.HIGH + 1); | ||||
|         indicators = openmct.indicators.getIndicatorObjectsByPriority(); | ||||
|  | ||||
|         expect(indicators[0].key).toEqual('test-indicator-2'); | ||||
|     }); | ||||
|  | ||||
|     it("the simple indicator can be added", () => { | ||||
|   | ||||
| @@ -27,10 +27,11 @@ import { convertTemplateToHTML } from '@/utils/template/templateHelpers'; | ||||
| const DEFAULT_ICON_CLASS = 'icon-info'; | ||||
|  | ||||
| class SimpleIndicator extends EventEmitter { | ||||
|     constructor(openmct) { | ||||
|     constructor(openmct, key) { | ||||
|         super(); | ||||
|  | ||||
|         this.openmct = openmct; | ||||
|         this.key = key; | ||||
|         this.element = convertTemplateToHTML(indicatorTemplate)[0]; | ||||
|         this.priority = openmct.priority.DEFAULT; | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,7 @@ define(['./URLIndicator'], | ||||
|     function URLIndicatorPlugin(URLIndicator) { | ||||
|         return function (opts) { | ||||
|             return function install(openmct) { | ||||
|                 const simpleIndicator = openmct.indicators.simpleIndicator(); | ||||
|                 const simpleIndicator = openmct.indicators.simpleIndicator('url-indicator'); | ||||
|                 const urlIndicator = new URLIndicator(opts, simpleIndicator); | ||||
|  | ||||
|                 openmct.indicators.add(simpleIndicator); | ||||
|   | ||||
| @@ -56,85 +56,76 @@ describe("The URLTimeSettingsSynchronizer", () => { | ||||
|     it("initial clock is set to fixed is reflected in URL", (done) => { | ||||
|         resolveFunction = () => { | ||||
|             oldHash = window.location.hash; | ||||
|             expect(window.location.hash.includes('tc.mode=fixed')).toBe(true); | ||||
|             expect(window.location.hash).toContain('tc.mode=fixed'); | ||||
|  | ||||
|             openmct.router.removeListener('change:hash', resolveFunction); | ||||
|             done(); | ||||
|         }; | ||||
|  | ||||
|         // We have a debounce set to 300ms on setHash, so if we don't flush, | ||||
|         // the above resolve function sometimes doesn't fire due to a race condition. | ||||
|         openmct.router.setHash.flush(); | ||||
|         openmct.router.on('change:hash', resolveFunction); | ||||
|     }); | ||||
|  | ||||
|     it("when the clock is set via the time API, it is reflected in the URL", (done) => { | ||||
|         let success; | ||||
|  | ||||
|         resolveFunction = () => { | ||||
|             openmct.time.clock('local', { | ||||
|                 start: -2000, | ||||
|                 end: 200 | ||||
|             }); | ||||
|  | ||||
|             const hasStartDelta = window.location.hash.includes('tc.startDelta=2000'); | ||||
|             const hasEndDelta = window.location.hash.includes('tc.endDelta=200'); | ||||
|             const hasLocalClock = window.location.hash.includes('tc.mode=local'); | ||||
|             success = hasStartDelta && hasEndDelta && hasLocalClock; | ||||
|             if (success) { | ||||
|                 expect(success).toBe(true); | ||||
|  | ||||
|                 openmct.router.removeListener('change:hash', resolveFunction); | ||||
|                 done(); | ||||
|             } | ||||
|             openmct.router.setHash.flush(); | ||||
|             const urlHash = window.location.hash; | ||||
|             expect(urlHash).toContain('tc.startDelta=2000'); | ||||
|             expect(urlHash).toContain('tc.endDelta=200'); | ||||
|             expect(urlHash).toContain('tc.mode=local'); | ||||
|             openmct.router.removeListener('change:hash', resolveFunction); | ||||
|             done(); | ||||
|         }; | ||||
|  | ||||
|         // We have a debounce set to 300ms on setHash, so if we don't flush, | ||||
|         // the above resolve function sometimes doesn't fire due to a race condition. | ||||
|         openmct.router.setHash.flush(); | ||||
|         openmct.router.on('change:hash', resolveFunction); | ||||
|     }); | ||||
|  | ||||
|     it("when the clock mode is set to local, it is reflected in the URL", (done) => { | ||||
|         let success; | ||||
|  | ||||
|         resolveFunction = () => { | ||||
|             let hash = window.location.hash; | ||||
|             hash = hash.replace('tc.mode=fixed', 'tc.mode=local'); | ||||
|             window.location.hash = hash; | ||||
|  | ||||
|             success = window.location.hash.includes('tc.mode=local'); | ||||
|             if (success) { | ||||
|                 expect(success).toBe(true); | ||||
|                 done(); | ||||
|             } | ||||
|             expect(window.location.hash).toContain('tc.mode=local'); | ||||
|             done(); | ||||
|         }; | ||||
|  | ||||
|         // We have a debounce set to 300ms on setHash, so if we don't flush, | ||||
|         // the above resolve function sometimes doesn't fire due to a race condition. | ||||
|         openmct.router.setHash.flush(); | ||||
|         openmct.router.on('change:hash', resolveFunction); | ||||
|     }); | ||||
|  | ||||
|     it("when the clock mode is set to local, it is reflected in the URL", (done) => { | ||||
|         let success; | ||||
|  | ||||
|         resolveFunction = () => { | ||||
|             let hash = window.location.hash; | ||||
|  | ||||
|             hash = hash.replace('tc.mode=fixed', 'tc.mode=local'); | ||||
|             window.location.hash = hash; | ||||
|             success = window.location.hash.includes('tc.mode=local'); | ||||
|             if (success) { | ||||
|                 expect(success).toBe(true); | ||||
|                 done(); | ||||
|             } | ||||
|             expect(window.location.hash).toContain('tc.mode=local'); | ||||
|             done(); | ||||
|         }; | ||||
|  | ||||
|         // We have a debounce set to 300ms on setHash, so if we don't flush, | ||||
|         // the above resolve function sometimes doesn't fire due to a race condition. | ||||
|         openmct.router.setHash.flush(); | ||||
|         openmct.router.on('change:hash', resolveFunction); | ||||
|     }); | ||||
|  | ||||
|     it("reset hash", (done) => { | ||||
|         let success; | ||||
|  | ||||
|         window.location.hash = oldHash; | ||||
|         resolveFunction = () => { | ||||
|             success = window.location.hash === oldHash; | ||||
|             if (success) { | ||||
|                 expect(success).toBe(true); | ||||
|                 done(); | ||||
|             } | ||||
|             expect(window.location.hash).toBe(oldHash); | ||||
|             done(); | ||||
|         }; | ||||
|  | ||||
|         openmct.router.on('change:hash', resolveFunction); | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <template> | ||||
| <button | ||||
|     class="c-popup-menu-button c-disclosure-button" | ||||
|     title="popup menu" | ||||
|     title="Open context menu" | ||||
|     @click="showMenuItems" | ||||
| > | ||||
| </button> | ||||
| @@ -65,6 +65,10 @@ export default { | ||||
|             return; | ||||
|         }, | ||||
|         showMenuItems($event) { | ||||
|             if (this.menuItems) { | ||||
|                 this.hideMenuItems(); | ||||
|             } | ||||
|  | ||||
|             const menuItems = new Vue({ | ||||
|                 components: { | ||||
|                     MenuItems | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export default class OperatorStatusIndicator extends AbstractStatusIndicator { | ||||
|     } | ||||
|  | ||||
|     createIndicator() { | ||||
|         const operatorIndicator = this.openmct.indicators.simpleIndicator(); | ||||
|         const operatorIndicator = this.openmct.indicators.simpleIndicator('operator-indicator'); | ||||
|  | ||||
|         operatorIndicator.text("My Operator Status"); | ||||
|         operatorIndicator.description("Set my operator status"); | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export default class PollQuestionIndicator extends AbstractStatusIndicator { | ||||
|     } | ||||
|  | ||||
|     createIndicator() { | ||||
|         const pollQuestionIndicator = this.openmct.indicators.simpleIndicator(); | ||||
|         const pollQuestionIndicator = this.openmct.indicators.simpleIndicator('poll-question-indicator'); | ||||
|  | ||||
|         pollQuestionIndicator.text("Poll Question"); | ||||
|         pollQuestionIndicator.description("Set the current poll question"); | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export default function PerformanceIndicator() { | ||||
|     return function install(openmct) { | ||||
|         let frames = 0; | ||||
|         let lastCalculated = performance.now(); | ||||
|         const indicator = openmct.indicators.simpleIndicator(); | ||||
|         const indicator = openmct.indicators.simpleIndicator('performance-indicator'); | ||||
|  | ||||
|         indicator.text('~ fps'); | ||||
|         indicator.statusClass('s-status-info'); | ||||
|   | ||||
| @@ -30,7 +30,7 @@ const COUCH_SEARCH_ONLY_NAMESPACE = `COUCH_SEARCH_${Date.now()}`; | ||||
|  | ||||
| export default function CouchPlugin(options) { | ||||
|     return function install(openmct) { | ||||
|         const simpleIndicator = openmct.indicators.simpleIndicator(); | ||||
|         const simpleIndicator = openmct.indicators.simpleIndicator('couch-indicator'); | ||||
|         openmct.indicators.add(simpleIndicator); | ||||
|         const couchStatusIndicator = new CouchStatusIndicator(simpleIndicator); | ||||
|         install.couchProvider = new CouchObjectProvider(openmct, options, NAMESPACE, couchStatusIndicator); | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/plugins/persistence/couch/setup-couchdb.sh
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										15
									
								
								src/plugins/persistence/couch/setup-couchdb.sh
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -83,9 +83,13 @@ create_admin_user () { | ||||
|     curl -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/admins/$COUCH_ADMIN_USER -d \'"$COUCH_ADMIN_PASSWORD"\' | ||||
| } | ||||
|  | ||||
| is_cors_enabled() { | ||||
|     resource_exists $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/httpd/enable_cors | ||||
| } | ||||
|  | ||||
| enable_cors () { | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/httpd/enable_cors -d '"true"' | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/cors/origins -d '"http://localhost:8080"' | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/cors/origins -d '"*"' | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/cors/credentials -d '"true"' | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/cors/methods -d '"GET, PUT, POST, HEAD, DELETE"' | ||||
|     curl -su "${CURL_USERPASS_ARG}" -o /dev/null -X PUT $COUCH_BASE_LOCAL/_node/$COUCH_NODE_NAME/_config/cors/headers -d '"accept, authorization, content-type, origin, referer, x-csrf-token"' | ||||
| @@ -132,6 +136,9 @@ else | ||||
|     echo "Database permissions not updated" | ||||
| fi | ||||
|  | ||||
| echo "Enabling CORS" | ||||
| enable_cors | ||||
| echo "CORS successfully enabled" | ||||
| if [ "FALSE" == $(is_cors_enabled) ]; then | ||||
|     echo "Enabling CORS" | ||||
|     enable_cors | ||||
| else | ||||
|     echo "CORS enabled, nothing to do" | ||||
| fi | ||||
|   | ||||
| @@ -95,6 +95,11 @@ export default { | ||||
|         }, | ||||
|         getPathsForObjects(objectsNeedingPaths) { | ||||
|             return Promise.all(objectsNeedingPaths.map(async (domainObject) => { | ||||
|                 if (!domainObject) { | ||||
|                     // user interrupted search, return back | ||||
|                     return null; | ||||
|                 } | ||||
|  | ||||
|                 const keyStringForObject = this.openmct.objects.makeKeyString(domainObject.identifier); | ||||
|                 const originalPathObjects = await this.openmct.objects.getOriginalPath(keyStringForObject); | ||||
|  | ||||
| @@ -127,12 +132,17 @@ export default { | ||||
|                 this.searchLoading = false; | ||||
|                 this.showSearchResults(); | ||||
|             } catch (error) { | ||||
|                 console.error(`😞 Error searching`, error); | ||||
|                 this.searchLoading = false; | ||||
|  | ||||
|                 if (this.abortSearchController) { | ||||
|                     delete this.abortSearchController; | ||||
|                 } | ||||
|  | ||||
|                 // Is this coming from the AbortController? | ||||
|                 // If so, we can swallow the error. If not, 🤮 it to console | ||||
|                 if (error.name !== 'AbortError') { | ||||
|                     console.error(`😞 Error searching`, error); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         showSearchResults() { | ||||
|   | ||||
| @@ -28,6 +28,9 @@ describe('Application router utility functions', () => { | ||||
|             }; | ||||
|  | ||||
|             openmct.router.on('change:hash', resolveFunction); | ||||
|             // We have a debounce set to 300ms on setHash, so if we don't flush, | ||||
|             // the above resolve function sometimes doesn't fire due to a race condition. | ||||
|             openmct.router.setHash.flush(); | ||||
|             openmct.router.setLocationFromUrl(); | ||||
|         }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user