mirror of
https://github.com/nasa/openmct.git
synced 2025-05-09 20:12:50 +00:00
chore: add prettier
(2/3): apply formatting, re-enable lint ci step (#6682)
* style: apply prettier formatting * fix: re-enable lint ci check
This commit is contained in:
parent
172e0b23fd
commit
caa7bc6fae
@ -13,12 +13,12 @@ executors:
|
|||||||
docker_layer_caching: true
|
docker_layer_caching: true
|
||||||
parameters:
|
parameters:
|
||||||
BUST_CACHE:
|
BUST_CACHE:
|
||||||
description: "Set this with the CircleCI UI Trigger Workflow button (boolean = true) to bust the cache!"
|
description: 'Set this with the CircleCI UI Trigger Workflow button (boolean = true) to bust the cache!'
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
commands:
|
commands:
|
||||||
build_and_install:
|
build_and_install:
|
||||||
description: "All steps used to build and install. Will use cache if found"
|
description: 'All steps used to build and install. Will use cache if found'
|
||||||
parameters:
|
parameters:
|
||||||
node-version:
|
node-version:
|
||||||
type: string
|
type: string
|
||||||
@ -30,19 +30,19 @@ commands:
|
|||||||
node-version: << parameters.node-version >>
|
node-version: << parameters.node-version >>
|
||||||
- run: npm install --no-audit --progress=false
|
- run: npm install --no-audit --progress=false
|
||||||
restore_cache_cmd:
|
restore_cache_cmd:
|
||||||
description: "Custom command for restoring cache with the ability to bust cache. When BUST_CACHE is set to true, jobs will not restore cache"
|
description: 'Custom command for restoring cache with the ability to bust cache. When BUST_CACHE is set to true, jobs will not restore cache'
|
||||||
parameters:
|
parameters:
|
||||||
node-version:
|
node-version:
|
||||||
type: string
|
type: string
|
||||||
steps:
|
steps:
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [false, << pipeline.parameters.BUST_CACHE >> ]
|
equal: [false, << pipeline.parameters.BUST_CACHE >>]
|
||||||
steps:
|
steps:
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
key: deps--{{ arch }}--{{ .Branch }}--<< parameters.node-version >>--{{ checksum "package.json" }}-{{ checksum ".circleci/config.yml" }}
|
key: deps--{{ arch }}--{{ .Branch }}--<< parameters.node-version >>--{{ checksum "package.json" }}-{{ checksum ".circleci/config.yml" }}
|
||||||
save_cache_cmd:
|
save_cache_cmd:
|
||||||
description: "Custom command for saving cache."
|
description: 'Custom command for saving cache.'
|
||||||
parameters:
|
parameters:
|
||||||
node-version:
|
node-version:
|
||||||
type: string
|
type: string
|
||||||
@ -53,7 +53,7 @@ commands:
|
|||||||
- ~/.npm
|
- ~/.npm
|
||||||
- node_modules
|
- node_modules
|
||||||
generate_and_store_version_and_filesystem_artifacts:
|
generate_and_store_version_and_filesystem_artifacts:
|
||||||
description: "Track important packages and files"
|
description: 'Track important packages and files'
|
||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
[[ $EUID -ne 0 ]] && (sudo mkdir -p /tmp/artifacts && sudo chmod 777 /tmp/artifacts) || (mkdir -p /tmp/artifacts && chmod 777 /tmp/artifacts)
|
[[ $EUID -ne 0 ]] && (sudo mkdir -p /tmp/artifacts && sudo chmod 777 /tmp/artifacts) || (mkdir -p /tmp/artifacts && chmod 777 /tmp/artifacts)
|
||||||
@ -64,7 +64,7 @@ commands:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /tmp/artifacts/
|
path: /tmp/artifacts/
|
||||||
generate_e2e_code_cov_report:
|
generate_e2e_code_cov_report:
|
||||||
description: "Generate e2e code coverage artifacts and publish to codecov.io. Needed to that we can ignore the exit code status of the npm run test"
|
description: 'Generate e2e code coverage artifacts and publish to codecov.io. Needed to that we can ignore the exit code status of the npm run test'
|
||||||
parameters:
|
parameters:
|
||||||
suite:
|
suite:
|
||||||
type: string
|
type: string
|
||||||
@ -115,7 +115,7 @@ jobs:
|
|||||||
path: coverage
|
path: coverage
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_and_store_version_and_filesystem_artifacts
|
- generate_and_store_version_and_filesystem_artifacts
|
||||||
e2e-test:
|
e2e-test:
|
||||||
@ -131,13 +131,13 @@ jobs:
|
|||||||
node-version: <<parameters.node-version>>
|
node-version: <<parameters.node-version>>
|
||||||
- when: #Only install chrome-beta when running the 'full' suite to save $$$
|
- when: #Only install chrome-beta when running the 'full' suite to save $$$
|
||||||
condition:
|
condition:
|
||||||
equal: [ "full", <<parameters.suite>> ]
|
equal: ['full', <<parameters.suite>>]
|
||||||
steps:
|
steps:
|
||||||
- run: npx playwright install chrome-beta
|
- run: npx playwright install chrome-beta
|
||||||
- run: SHARD="$((${CIRCLE_NODE_INDEX}+1))"; npm run test:e2e:<<parameters.suite>> -- --shard=${SHARD}/${CIRCLE_NODE_TOTAL}
|
- run: SHARD="$((${CIRCLE_NODE_INDEX}+1))"; npm run test:e2e:<<parameters.suite>> -- --shard=${SHARD}/${CIRCLE_NODE_TOTAL}
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_e2e_code_cov_report:
|
- generate_e2e_code_cov_report:
|
||||||
suite: <<parameters.suite>>
|
suite: <<parameters.suite>>
|
||||||
@ -151,7 +151,7 @@ jobs:
|
|||||||
path: html-test-results
|
path: html-test-results
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_and_store_version_and_filesystem_artifacts
|
- generate_and_store_version_and_filesystem_artifacts
|
||||||
e2e-couchdb:
|
e2e-couchdb:
|
||||||
@ -172,7 +172,7 @@ jobs:
|
|||||||
- run: npm run test:e2e:couchdb
|
- run: npm run test:e2e:couchdb
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_e2e_code_cov_report:
|
- generate_e2e_code_cov_report:
|
||||||
suite: full #add to full suite
|
suite: full #add to full suite
|
||||||
@ -186,7 +186,7 @@ jobs:
|
|||||||
path: html-test-results
|
path: html-test-results
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_and_store_version_and_filesystem_artifacts
|
- generate_and_store_version_and_filesystem_artifacts
|
||||||
perf-test:
|
perf-test:
|
||||||
@ -206,7 +206,7 @@ jobs:
|
|||||||
path: html-test-results
|
path: html-test-results
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always run codecov reports regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_and_store_version_and_filesystem_artifacts
|
- generate_and_store_version_and_filesystem_artifacts
|
||||||
visual-test:
|
visual-test:
|
||||||
@ -226,15 +226,15 @@ jobs:
|
|||||||
path: html-test-results
|
path: html-test-results
|
||||||
- when:
|
- when:
|
||||||
condition:
|
condition:
|
||||||
equal: [ 42, 42 ] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
equal: [42, 42] # Always generate version artifacts regardless of test failure https://discuss.circleci.com/t/make-custom-command-run-always-with-when-always/38957/2
|
||||||
steps:
|
steps:
|
||||||
- generate_and_store_version_and_filesystem_artifacts
|
- generate_and_store_version_and_filesystem_artifacts
|
||||||
workflows:
|
workflows:
|
||||||
overall-circleci-commit-status: #These jobs run on every commit
|
overall-circleci-commit-status: #These jobs run on every commit
|
||||||
jobs:
|
jobs:
|
||||||
# - lint:
|
- lint:
|
||||||
# name: node16-lint
|
name: node16-lint
|
||||||
# node-version: lts/gallium
|
node-version: lts/gallium
|
||||||
- unit-test:
|
- unit-test:
|
||||||
name: node18-chrome
|
name: node18-chrome
|
||||||
node-version: lts/hydrogen
|
node-version: lts/hydrogen
|
||||||
@ -269,7 +269,7 @@ workflows:
|
|||||||
node-version: lts/hydrogen
|
node-version: lts/hydrogen
|
||||||
triggers:
|
triggers:
|
||||||
- schedule:
|
- schedule:
|
||||||
cron: "0 0 * * *"
|
cron: '0 0 * * *'
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
|
210
.eslintrc.js
210
.eslintrc.js
@ -1,165 +1,165 @@
|
|||||||
const LEGACY_FILES = ["example/**"];
|
const LEGACY_FILES = ['example/**'];
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"env": {
|
env: {
|
||||||
"browser": true,
|
browser: true,
|
||||||
"es6": true,
|
es6: true,
|
||||||
"jasmine": true,
|
jasmine: true,
|
||||||
"amd": true
|
amd: true
|
||||||
},
|
},
|
||||||
"globals": {
|
globals: {
|
||||||
"_": "readonly"
|
_: 'readonly'
|
||||||
},
|
},
|
||||||
"plugins": ["prettier"],
|
plugins: ['prettier'],
|
||||||
"extends": [
|
extends: [
|
||||||
"eslint:recommended",
|
'eslint:recommended',
|
||||||
"plugin:compat/recommended",
|
'plugin:compat/recommended',
|
||||||
"plugin:vue/recommended",
|
'plugin:vue/recommended',
|
||||||
"plugin:you-dont-need-lodash-underscore/compatible",
|
'plugin:you-dont-need-lodash-underscore/compatible',
|
||||||
"plugin:prettier/recommended"
|
'plugin:prettier/recommended'
|
||||||
],
|
],
|
||||||
"parser": "vue-eslint-parser",
|
parser: 'vue-eslint-parser',
|
||||||
"parserOptions": {
|
parserOptions: {
|
||||||
"parser": "@babel/eslint-parser",
|
parser: '@babel/eslint-parser',
|
||||||
"requireConfigFile": false,
|
requireConfigFile: false,
|
||||||
"allowImportExportEverywhere": true,
|
allowImportExportEverywhere: true,
|
||||||
"ecmaVersion": 2015,
|
ecmaVersion: 2015,
|
||||||
"ecmaFeatures": {
|
ecmaFeatures: {
|
||||||
"impliedStrict": true
|
impliedStrict: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rules": {
|
rules: {
|
||||||
"prettier/prettier": "error",
|
'prettier/prettier': 'error',
|
||||||
"you-dont-need-lodash-underscore/omit": "off",
|
'you-dont-need-lodash-underscore/omit': 'off',
|
||||||
"you-dont-need-lodash-underscore/throttle": "off",
|
'you-dont-need-lodash-underscore/throttle': 'off',
|
||||||
"you-dont-need-lodash-underscore/flatten": "off",
|
'you-dont-need-lodash-underscore/flatten': 'off',
|
||||||
"you-dont-need-lodash-underscore/get": "off",
|
'you-dont-need-lodash-underscore/get': 'off',
|
||||||
"no-bitwise": "error",
|
'no-bitwise': 'error',
|
||||||
"curly": "error",
|
curly: 'error',
|
||||||
"eqeqeq": "error",
|
eqeqeq: 'error',
|
||||||
"guard-for-in": "error",
|
'guard-for-in': 'error',
|
||||||
"no-extend-native": "error",
|
'no-extend-native': 'error',
|
||||||
"no-inner-declarations": "off",
|
'no-inner-declarations': 'off',
|
||||||
"no-use-before-define": ["error", "nofunc"],
|
'no-use-before-define': ['error', 'nofunc'],
|
||||||
"no-caller": "error",
|
'no-caller': 'error',
|
||||||
"no-irregular-whitespace": "error",
|
'no-irregular-whitespace': 'error',
|
||||||
"no-new": "error",
|
'no-new': 'error',
|
||||||
"no-shadow": "error",
|
'no-shadow': 'error',
|
||||||
"no-undef": "error",
|
'no-undef': 'error',
|
||||||
"no-unused-vars": [
|
'no-unused-vars': [
|
||||||
"error",
|
'error',
|
||||||
{
|
{
|
||||||
"vars": "all",
|
vars: 'all',
|
||||||
"args": "none"
|
args: 'none'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"no-console": "off",
|
'no-console': 'off',
|
||||||
"new-cap": [
|
'new-cap': [
|
||||||
"error",
|
'error',
|
||||||
{
|
{
|
||||||
"capIsNew": false,
|
capIsNew: false,
|
||||||
"properties": false
|
properties: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dot-notation": "error",
|
'dot-notation': 'error',
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-case-declarations
|
// https://eslint.org/docs/rules/no-case-declarations
|
||||||
"no-case-declarations": "error",
|
'no-case-declarations': 'error',
|
||||||
// https://eslint.org/docs/rules/max-classes-per-file
|
// https://eslint.org/docs/rules/max-classes-per-file
|
||||||
"max-classes-per-file": ["error", 1],
|
'max-classes-per-file': ['error', 1],
|
||||||
// https://eslint.org/docs/rules/no-eq-null
|
// https://eslint.org/docs/rules/no-eq-null
|
||||||
"no-eq-null": "error",
|
'no-eq-null': 'error',
|
||||||
// https://eslint.org/docs/rules/no-eval
|
// https://eslint.org/docs/rules/no-eval
|
||||||
"no-eval": "error",
|
'no-eval': 'error',
|
||||||
// https://eslint.org/docs/rules/no-implicit-globals
|
// https://eslint.org/docs/rules/no-implicit-globals
|
||||||
"no-implicit-globals": "error",
|
'no-implicit-globals': 'error',
|
||||||
// https://eslint.org/docs/rules/no-implied-eval
|
// https://eslint.org/docs/rules/no-implied-eval
|
||||||
"no-implied-eval": "error",
|
'no-implied-eval': 'error',
|
||||||
// https://eslint.org/docs/rules/no-lone-blocks
|
// https://eslint.org/docs/rules/no-lone-blocks
|
||||||
"no-lone-blocks": "error",
|
'no-lone-blocks': 'error',
|
||||||
// https://eslint.org/docs/rules/no-loop-func
|
// https://eslint.org/docs/rules/no-loop-func
|
||||||
"no-loop-func": "error",
|
'no-loop-func': 'error',
|
||||||
// https://eslint.org/docs/rules/no-new-func
|
// https://eslint.org/docs/rules/no-new-func
|
||||||
"no-new-func": "error",
|
'no-new-func': 'error',
|
||||||
// https://eslint.org/docs/rules/no-new-wrappers
|
// https://eslint.org/docs/rules/no-new-wrappers
|
||||||
"no-new-wrappers": "error",
|
'no-new-wrappers': 'error',
|
||||||
// https://eslint.org/docs/rules/no-octal-escape
|
// https://eslint.org/docs/rules/no-octal-escape
|
||||||
"no-octal-escape": "error",
|
'no-octal-escape': 'error',
|
||||||
// https://eslint.org/docs/rules/no-proto
|
// https://eslint.org/docs/rules/no-proto
|
||||||
"no-proto": "error",
|
'no-proto': 'error',
|
||||||
// https://eslint.org/docs/rules/no-return-await
|
// https://eslint.org/docs/rules/no-return-await
|
||||||
"no-return-await": "error",
|
'no-return-await': 'error',
|
||||||
// https://eslint.org/docs/rules/no-script-url
|
// https://eslint.org/docs/rules/no-script-url
|
||||||
"no-script-url": "error",
|
'no-script-url': 'error',
|
||||||
// https://eslint.org/docs/rules/no-self-compare
|
// https://eslint.org/docs/rules/no-self-compare
|
||||||
"no-self-compare": "error",
|
'no-self-compare': 'error',
|
||||||
// https://eslint.org/docs/rules/no-sequences
|
// https://eslint.org/docs/rules/no-sequences
|
||||||
"no-sequences": "error",
|
'no-sequences': 'error',
|
||||||
// https://eslint.org/docs/rules/no-unmodified-loop-condition
|
// https://eslint.org/docs/rules/no-unmodified-loop-condition
|
||||||
"no-unmodified-loop-condition": "error",
|
'no-unmodified-loop-condition': 'error',
|
||||||
// https://eslint.org/docs/rules/no-useless-call
|
// https://eslint.org/docs/rules/no-useless-call
|
||||||
"no-useless-call": "error",
|
'no-useless-call': 'error',
|
||||||
// https://eslint.org/docs/rules/no-nested-ternary
|
// https://eslint.org/docs/rules/no-nested-ternary
|
||||||
"no-nested-ternary": "error",
|
'no-nested-ternary': 'error',
|
||||||
// https://eslint.org/docs/rules/no-useless-computed-key
|
// https://eslint.org/docs/rules/no-useless-computed-key
|
||||||
"no-useless-computed-key": "error",
|
'no-useless-computed-key': 'error',
|
||||||
// https://eslint.org/docs/rules/no-var
|
// https://eslint.org/docs/rules/no-var
|
||||||
"no-var": "error",
|
'no-var': 'error',
|
||||||
// https://eslint.org/docs/rules/one-var
|
// https://eslint.org/docs/rules/one-var
|
||||||
"one-var": ["error", "never"],
|
'one-var': ['error', 'never'],
|
||||||
// https://eslint.org/docs/rules/default-case-last
|
// https://eslint.org/docs/rules/default-case-last
|
||||||
"default-case-last": "error",
|
'default-case-last': 'error',
|
||||||
// https://eslint.org/docs/rules/default-param-last
|
// https://eslint.org/docs/rules/default-param-last
|
||||||
"default-param-last": "error",
|
'default-param-last': 'error',
|
||||||
// https://eslint.org/docs/rules/grouped-accessor-pairs
|
// https://eslint.org/docs/rules/grouped-accessor-pairs
|
||||||
"grouped-accessor-pairs": "error",
|
'grouped-accessor-pairs': 'error',
|
||||||
// https://eslint.org/docs/rules/no-constructor-return
|
// https://eslint.org/docs/rules/no-constructor-return
|
||||||
"no-constructor-return": "error",
|
'no-constructor-return': 'error',
|
||||||
// https://eslint.org/docs/rules/array-callback-return
|
// https://eslint.org/docs/rules/array-callback-return
|
||||||
"array-callback-return": "error",
|
'array-callback-return': 'error',
|
||||||
// https://eslint.org/docs/rules/no-invalid-this
|
// https://eslint.org/docs/rules/no-invalid-this
|
||||||
"no-invalid-this": "error", // Believe this one actually surfaces some bugs
|
'no-invalid-this': 'error', // Believe this one actually surfaces some bugs
|
||||||
// https://eslint.org/docs/rules/func-style
|
// https://eslint.org/docs/rules/func-style
|
||||||
"func-style": ["error", "declaration"],
|
'func-style': ['error', 'declaration'],
|
||||||
// https://eslint.org/docs/rules/no-unused-expressions
|
// https://eslint.org/docs/rules/no-unused-expressions
|
||||||
"no-unused-expressions": "error",
|
'no-unused-expressions': 'error',
|
||||||
// https://eslint.org/docs/rules/no-useless-concat
|
// https://eslint.org/docs/rules/no-useless-concat
|
||||||
"no-useless-concat": "error",
|
'no-useless-concat': 'error',
|
||||||
// https://eslint.org/docs/rules/radix
|
// https://eslint.org/docs/rules/radix
|
||||||
"radix": "error",
|
radix: 'error',
|
||||||
// https://eslint.org/docs/rules/require-await
|
// https://eslint.org/docs/rules/require-await
|
||||||
"require-await": "error",
|
'require-await': 'error',
|
||||||
// https://eslint.org/docs/rules/no-alert
|
// https://eslint.org/docs/rules/no-alert
|
||||||
"no-alert": "error",
|
'no-alert': 'error',
|
||||||
// https://eslint.org/docs/rules/no-useless-constructor
|
// https://eslint.org/docs/rules/no-useless-constructor
|
||||||
"no-useless-constructor": "error",
|
'no-useless-constructor': 'error',
|
||||||
// https://eslint.org/docs/rules/no-duplicate-imports
|
// https://eslint.org/docs/rules/no-duplicate-imports
|
||||||
"no-duplicate-imports": "error",
|
'no-duplicate-imports': 'error',
|
||||||
|
|
||||||
// https://eslint.org/docs/rules/no-implicit-coercion
|
// https://eslint.org/docs/rules/no-implicit-coercion
|
||||||
"no-implicit-coercion": "error",
|
'no-implicit-coercion': 'error',
|
||||||
//https://eslint.org/docs/rules/no-unneeded-ternary
|
//https://eslint.org/docs/rules/no-unneeded-ternary
|
||||||
"no-unneeded-ternary": "error",
|
'no-unneeded-ternary': 'error',
|
||||||
"vue/first-attribute-linebreak": "error",
|
'vue/first-attribute-linebreak': 'error',
|
||||||
"vue/multiline-html-element-content-newline": "off",
|
'vue/multiline-html-element-content-newline': 'off',
|
||||||
"vue/singleline-html-element-content-newline": "off",
|
'vue/singleline-html-element-content-newline': 'off',
|
||||||
"vue/multi-word-component-names": "off", // TODO enable, align with conventions
|
'vue/multi-word-component-names': 'off', // TODO enable, align with conventions
|
||||||
"vue/no-mutating-props": "off"
|
'vue/no-mutating-props': 'off'
|
||||||
},
|
},
|
||||||
"overrides": [
|
overrides: [
|
||||||
{
|
{
|
||||||
"files": LEGACY_FILES,
|
files: LEGACY_FILES,
|
||||||
"rules": {
|
rules: {
|
||||||
"no-unused-vars": [
|
'no-unused-vars': [
|
||||||
"warn",
|
'warn',
|
||||||
{
|
{
|
||||||
"vars": "all",
|
vars: 'all',
|
||||||
"args": "none",
|
args: 'none',
|
||||||
"varsIgnorePattern": "controller"
|
varsIgnorePattern: 'controller'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"no-nested-ternary": "off",
|
'no-nested-ternary': 'off',
|
||||||
"no-var": "off",
|
'no-var': 'off',
|
||||||
"one-var": "off"
|
'one-var': 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
57
.github/dependabot.yml
vendored
57
.github/dependabot.yml
vendored
@ -1,39 +1,38 @@
|
|||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: 'npm'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: 'weekly'
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
labels:
|
labels:
|
||||||
- "pr:daveit"
|
- 'pr:daveit'
|
||||||
- "pr:e2e"
|
- 'pr:e2e'
|
||||||
- "type:maintenance"
|
- 'type:maintenance'
|
||||||
- "dependencies"
|
- 'dependencies'
|
||||||
- "pr:platform"
|
- 'pr:platform'
|
||||||
ignore:
|
ignore:
|
||||||
#We have to source the playwright container which is not detected by Dependabot
|
#We have to source the playwright container which is not detected by Dependabot
|
||||||
- dependency-name: "@playwright/test"
|
- dependency-name: '@playwright/test'
|
||||||
- dependency-name: "playwright-core"
|
- dependency-name: 'playwright-core'
|
||||||
#Lots of noise in these type patch releases.
|
#Lots of noise in these type patch releases.
|
||||||
- dependency-name: "@babel/eslint-parser"
|
- dependency-name: '@babel/eslint-parser'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- dependency-name: "eslint-plugin-vue"
|
- dependency-name: 'eslint-plugin-vue'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- dependency-name: "babel-loader"
|
- dependency-name: 'babel-loader'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- dependency-name: "sinon"
|
- dependency-name: 'sinon'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- dependency-name: "moment-timezone"
|
- dependency-name: 'moment-timezone'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- dependency-name: "@types/lodash"
|
- dependency-name: '@types/lodash'
|
||||||
update-types: ["version-update:semver-patch"]
|
update-types: ['version-update:semver-patch']
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: 'github-actions'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
labels:
|
labels:
|
||||||
- "pr:daveit"
|
- 'pr:daveit'
|
||||||
- "type:maintenance"
|
- 'type:maintenance'
|
||||||
- "dependencies"
|
- 'dependencies'
|
||||||
|
4
.github/workflows/e2e-couchdb.yml
vendored
4
.github/workflows/e2e-couchdb.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: "e2e-couchdb"
|
name: 'e2e-couchdb'
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -17,7 +17,7 @@ jobs:
|
|||||||
- run: npx playwright@1.32.3 install
|
- run: npx playwright@1.32.3 install
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- name: Start CouchDB Docker Container and Init with Setup Scripts
|
- name: Start CouchDB Docker Container and Init with Setup Scripts
|
||||||
run : |
|
run: |
|
||||||
export $(cat src/plugins/persistence/couch/.env.ci | xargs)
|
export $(cat src/plugins/persistence/couch/.env.ci | xargs)
|
||||||
docker-compose -f src/plugins/persistence/couch/couchdb-compose.yaml up --detach
|
docker-compose -f src/plugins/persistence/couch/couchdb-compose.yaml up --detach
|
||||||
sleep 3
|
sleep 3
|
||||||
|
2
.github/workflows/e2e-pr.yml
vendored
2
.github/workflows/e2e-pr.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: "e2e-pr"
|
name: 'e2e-pr'
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
4
.github/workflows/pr-platform.yml
vendored
4
.github/workflows/pr-platform.yml
vendored
@ -1,8 +1,8 @@
|
|||||||
name: "pr-platform"
|
name: 'pr-platform'
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [ labeled ]
|
types: [labeled]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
e2e-full:
|
e2e-full:
|
||||||
|
2
.github/workflows/prcop.yml
vendored
2
.github/workflows/prcop.yml
vendored
@ -22,5 +22,5 @@ jobs:
|
|||||||
- name: Linting Pull Request
|
- name: Linting Pull Request
|
||||||
uses: makaroni4/prcop@v1.0.35
|
uses: makaroni4/prcop@v1.0.35
|
||||||
with:
|
with:
|
||||||
config-file: ".github/workflows/prcop-config.json"
|
config-file: '.github/workflows/prcop-config.json'
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -8,80 +8,67 @@ This is the OpenMCT common webpack file. It is imported by the other three webpa
|
|||||||
There are separate npm scripts to use these configurations, though simply running `npm install`
|
There are separate npm scripts to use these configurations, though simply running `npm install`
|
||||||
will use the default production configuration.
|
will use the default production configuration.
|
||||||
*/
|
*/
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
const packageDefinition = require("../package.json");
|
const packageDefinition = require('../package.json');
|
||||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
const webpack = require("webpack");
|
const webpack = require('webpack');
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
|
||||||
const { VueLoaderPlugin } = require("vue-loader");
|
const { VueLoaderPlugin } = require('vue-loader');
|
||||||
let gitRevision = "error-retrieving-revision";
|
let gitRevision = 'error-retrieving-revision';
|
||||||
let gitBranch = "error-retrieving-branch";
|
let gitBranch = 'error-retrieving-branch';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
gitRevision = require("child_process")
|
gitRevision = require('child_process').execSync('git rev-parse HEAD').toString().trim();
|
||||||
.execSync("git rev-parse HEAD")
|
gitBranch = require('child_process')
|
||||||
.toString()
|
.execSync('git rev-parse --abbrev-ref HEAD')
|
||||||
.trim();
|
|
||||||
gitBranch = require("child_process")
|
|
||||||
.execSync("git rev-parse --abbrev-ref HEAD")
|
|
||||||
.toString()
|
.toString()
|
||||||
.trim();
|
.trim();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(err);
|
console.warn(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectRootDir = path.resolve(__dirname, "..");
|
const projectRootDir = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
/** @type {import('webpack').Configuration} */
|
/** @type {import('webpack').Configuration} */
|
||||||
const config = {
|
const config = {
|
||||||
context: projectRootDir,
|
context: projectRootDir,
|
||||||
entry: {
|
entry: {
|
||||||
openmct: "./openmct.js",
|
openmct: './openmct.js',
|
||||||
generatorWorker: "./example/generator/generatorWorker.js",
|
generatorWorker: './example/generator/generatorWorker.js',
|
||||||
couchDBChangesFeed:
|
couchDBChangesFeed: './src/plugins/persistence/couch/CouchChangesFeed.js',
|
||||||
"./src/plugins/persistence/couch/CouchChangesFeed.js",
|
inMemorySearchWorker: './src/api/objects/InMemorySearchWorker.js',
|
||||||
inMemorySearchWorker: "./src/api/objects/InMemorySearchWorker.js",
|
espressoTheme: './src/plugins/themes/espresso-theme.scss',
|
||||||
espressoTheme: "./src/plugins/themes/espresso-theme.scss",
|
snowTheme: './src/plugins/themes/snow-theme.scss'
|
||||||
snowTheme: "./src/plugins/themes/snow-theme.scss"
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
globalObject: "this",
|
globalObject: 'this',
|
||||||
filename: "[name].js",
|
filename: '[name].js',
|
||||||
path: path.resolve(projectRootDir, "dist"),
|
path: path.resolve(projectRootDir, 'dist'),
|
||||||
library: "openmct",
|
library: 'openmct',
|
||||||
libraryTarget: "umd",
|
libraryTarget: 'umd',
|
||||||
publicPath: "",
|
publicPath: '',
|
||||||
hashFunction: "xxhash64",
|
hashFunction: 'xxhash64',
|
||||||
clean: true
|
clean: true
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.join(projectRootDir, "src"),
|
'@': path.join(projectRootDir, 'src'),
|
||||||
legacyRegistry: path.join(projectRootDir, "src/legacyRegistry"),
|
legacyRegistry: path.join(projectRootDir, 'src/legacyRegistry'),
|
||||||
saveAs: "file-saver/src/FileSaver.js",
|
saveAs: 'file-saver/src/FileSaver.js',
|
||||||
csv: "comma-separated-values",
|
csv: 'comma-separated-values',
|
||||||
EventEmitter: "eventemitter3",
|
EventEmitter: 'eventemitter3',
|
||||||
bourbon: "bourbon.scss",
|
bourbon: 'bourbon.scss',
|
||||||
"plotly-basic": "plotly.js-basic-dist",
|
'plotly-basic': 'plotly.js-basic-dist',
|
||||||
"plotly-gl2d": "plotly.js-gl2d-dist",
|
'plotly-gl2d': 'plotly.js-gl2d-dist',
|
||||||
"d3-scale": path.join(
|
'd3-scale': path.join(projectRootDir, 'node_modules/d3-scale/dist/d3-scale.min.js'),
|
||||||
projectRootDir,
|
printj: path.join(projectRootDir, 'node_modules/printj/dist/printj.min.js'),
|
||||||
"node_modules/d3-scale/dist/d3-scale.min.js"
|
styles: path.join(projectRootDir, 'src/styles'),
|
||||||
),
|
MCT: path.join(projectRootDir, 'src/MCT'),
|
||||||
printj: path.join(
|
testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'),
|
||||||
projectRootDir,
|
objectUtils: path.join(projectRootDir, 'src/api/objects/object-utils.js'),
|
||||||
"node_modules/printj/dist/printj.min.js"
|
kdbush: path.join(projectRootDir, 'node_modules/kdbush/kdbush.min.js'),
|
||||||
),
|
utils: path.join(projectRootDir, 'src/utils')
|
||||||
styles: path.join(projectRootDir, "src/styles"),
|
|
||||||
MCT: path.join(projectRootDir, "src/MCT"),
|
|
||||||
testUtils: path.join(projectRootDir, "src/utils/testUtils.js"),
|
|
||||||
objectUtils: path.join(
|
|
||||||
projectRootDir,
|
|
||||||
"src/api/objects/object-utils.js"
|
|
||||||
),
|
|
||||||
"kdbush": path.join(projectRootDir, "node_modules/kdbush/kdbush.min.js"),
|
|
||||||
utils: path.join(projectRootDir, "src/utils")
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -95,24 +82,24 @@ const config = {
|
|||||||
new CopyWebpackPlugin({
|
new CopyWebpackPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
{
|
{
|
||||||
from: "src/images/favicons",
|
from: 'src/images/favicons',
|
||||||
to: "favicons"
|
to: 'favicons'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: "./index.html",
|
from: './index.html',
|
||||||
transform: function (content) {
|
transform: function (content) {
|
||||||
return content.toString().replace(/dist\//g, "");
|
return content.toString().replace(/dist\//g, '');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: "src/plugins/imagery/layers",
|
from: 'src/plugins/imagery/layers',
|
||||||
to: "imagery"
|
to: 'imagery'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: "[name].css",
|
filename: '[name].css',
|
||||||
chunkFilename: "[name].css"
|
chunkFilename: '[name].css'
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
module: {
|
module: {
|
||||||
@ -122,49 +109,49 @@ const config = {
|
|||||||
use: [
|
use: [
|
||||||
MiniCssExtractPlugin.loader,
|
MiniCssExtractPlugin.loader,
|
||||||
{
|
{
|
||||||
loader: "css-loader"
|
loader: 'css-loader'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: "resolve-url-loader"
|
loader: 'resolve-url-loader'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: "sass-loader",
|
loader: 'sass-loader',
|
||||||
options: { sourceMap: true }
|
options: { sourceMap: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.vue$/,
|
test: /\.vue$/,
|
||||||
use: "vue-loader"
|
use: 'vue-loader'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.html$/,
|
test: /\.html$/,
|
||||||
type: "asset/source"
|
type: 'asset/source'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(jpg|jpeg|png|svg)$/,
|
test: /\.(jpg|jpeg|png|svg)$/,
|
||||||
type: "asset/resource",
|
type: 'asset/resource',
|
||||||
generator: {
|
generator: {
|
||||||
filename: "images/[name][ext]"
|
filename: 'images/[name][ext]'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.ico$/,
|
test: /\.ico$/,
|
||||||
type: "asset/resource",
|
type: 'asset/resource',
|
||||||
generator: {
|
generator: {
|
||||||
filename: "icons/[name][ext]"
|
filename: 'icons/[name][ext]'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(woff|woff2?|eot|ttf)$/,
|
test: /\.(woff|woff2?|eot|ttf)$/,
|
||||||
type: "asset/resource",
|
type: 'asset/resource',
|
||||||
generator: {
|
generator: {
|
||||||
filename: "fonts/[name][ext]"
|
filename: 'fonts/[name][ext]'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
stats: "errors-warnings",
|
stats: 'errors-warnings',
|
||||||
performance: {
|
performance: {
|
||||||
// We should eventually consider chunking to decrease
|
// We should eventually consider chunking to decrease
|
||||||
// these values
|
// these values
|
||||||
|
@ -6,9 +6,9 @@ OpenMCT Continuous Integration servers use this configuration to add code covera
|
|||||||
information to pull requests.
|
information to pull requests.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const config = require("./webpack.dev");
|
const config = require('./webpack.dev');
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
const CI = process.env.CI === "true";
|
const CI = process.env.CI === 'true';
|
||||||
|
|
||||||
config.devtool = CI ? false : undefined;
|
config.devtool = CI ? false : undefined;
|
||||||
|
|
||||||
@ -18,15 +18,15 @@ config.module.rules.push({
|
|||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
exclude: /(Spec\.js$)|(node_modules)/,
|
exclude: /(Spec\.js$)|(node_modules)/,
|
||||||
use: {
|
use: {
|
||||||
loader: "babel-loader",
|
loader: 'babel-loader',
|
||||||
options: {
|
options: {
|
||||||
retainLines: true,
|
retainLines: true,
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
plugins: [
|
plugins: [
|
||||||
[
|
[
|
||||||
"babel-plugin-istanbul",
|
'babel-plugin-istanbul',
|
||||||
{
|
{
|
||||||
extension: [".js", ".vue"]
|
extension: ['.js', '.vue']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -5,29 +5,29 @@ This configuration should be used for development purposes. It contains full sou
|
|||||||
devServer (which be invoked using by `npm start`), and a non-minified Vue.js distribution.
|
devServer (which be invoked using by `npm start`), and a non-minified Vue.js distribution.
|
||||||
If OpenMCT is to be used for a production server, use webpack.prod.js instead.
|
If OpenMCT is to be used for a production server, use webpack.prod.js instead.
|
||||||
*/
|
*/
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
const webpack = require("webpack");
|
const webpack = require('webpack');
|
||||||
const { merge } = require("webpack-merge");
|
const { merge } = require('webpack-merge');
|
||||||
|
|
||||||
const common = require("./webpack.common");
|
const common = require('./webpack.common');
|
||||||
const projectRootDir = path.resolve(__dirname, "..");
|
const projectRootDir = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: "development",
|
mode: 'development',
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
// Since we use require.context, webpack is watching the entire directory.
|
// Since we use require.context, webpack is watching the entire directory.
|
||||||
// We need to exclude any files we don't want webpack to watch.
|
// We need to exclude any files we don't want webpack to watch.
|
||||||
// See: https://webpack.js.org/configuration/watch/#watchoptions-exclude
|
// See: https://webpack.js.org/configuration/watch/#watchoptions-exclude
|
||||||
ignored: [
|
ignored: [
|
||||||
"**/{node_modules,dist,docs,e2e}", // All files in node_modules, dist, docs, e2e,
|
'**/{node_modules,dist,docs,e2e}', // All files in node_modules, dist, docs, e2e,
|
||||||
"**/{*.yml,Procfile,webpack*.js,babel*.js,package*.json,tsconfig.json}", // Config files
|
'**/{*.yml,Procfile,webpack*.js,babel*.js,package*.json,tsconfig.json}', // Config files
|
||||||
"**/*.{sh,md,png,ttf,woff,svg}", // Non source files
|
'**/*.{sh,md,png,ttf,woff,svg}', // Non source files
|
||||||
"**/.*" // dotfiles and dotfolders
|
'**/.*' // dotfiles and dotfolders
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
vue: path.join(projectRootDir, "node_modules/vue/dist/vue.js")
|
vue: path.join(projectRootDir, 'node_modules/vue/dist/vue.js')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -35,20 +35,20 @@ module.exports = merge(common, {
|
|||||||
__OPENMCT_ROOT_RELATIVE__: '"dist/"'
|
__OPENMCT_ROOT_RELATIVE__: '"dist/"'
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
devtool: "eval-source-map",
|
devtool: 'eval-source-map',
|
||||||
devServer: {
|
devServer: {
|
||||||
devMiddleware: {
|
devMiddleware: {
|
||||||
writeToDisk: (filePathString) => {
|
writeToDisk: (filePathString) => {
|
||||||
const filePath = path.parse(filePathString);
|
const filePath = path.parse(filePathString);
|
||||||
const shouldWrite = !filePath.base.includes("hot-update");
|
const shouldWrite = !filePath.base.includes('hot-update');
|
||||||
|
|
||||||
return shouldWrite;
|
return shouldWrite;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watchFiles: ["**/*.css"],
|
watchFiles: ['**/*.css'],
|
||||||
static: {
|
static: {
|
||||||
directory: path.join(__dirname, "..", "/dist"),
|
directory: path.join(__dirname, '..', '/dist'),
|
||||||
publicPath: "/dist",
|
publicPath: '/dist',
|
||||||
watch: false
|
watch: false
|
||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
This configuration should be used for production installs.
|
This configuration should be used for production installs.
|
||||||
It is the default webpack configuration.
|
It is the default webpack configuration.
|
||||||
*/
|
*/
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
const webpack = require("webpack");
|
const webpack = require('webpack');
|
||||||
const { merge } = require("webpack-merge");
|
const { merge } = require('webpack-merge');
|
||||||
|
|
||||||
const common = require("./webpack.common");
|
const common = require('./webpack.common');
|
||||||
const projectRootDir = path.resolve(__dirname, "..");
|
const projectRootDir = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: "production",
|
mode: 'production',
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
vue: path.join(projectRootDir, "node_modules/vue/dist/vue.min.js")
|
vue: path.join(projectRootDir, 'node_modules/vue/dist/vue.min.js')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -23,5 +23,5 @@ module.exports = merge(common, {
|
|||||||
__OPENMCT_ROOT_RELATIVE__: '""'
|
__OPENMCT_ROOT_RELATIVE__: '""'
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
devtool: "source-map"
|
devtool: 'source-map'
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@ coverage:
|
|||||||
informational: true
|
informational: true
|
||||||
precision: 2
|
precision: 2
|
||||||
round: down
|
round: down
|
||||||
range: "66...100"
|
range: '66...100'
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
unit:
|
unit:
|
||||||
@ -22,7 +22,7 @@ flags:
|
|||||||
carryforward: true
|
carryforward: true
|
||||||
|
|
||||||
comment:
|
comment:
|
||||||
layout: "diff,flags,files,footer"
|
layout: 'diff,flags,files,footer'
|
||||||
behavior: default
|
behavior: default
|
||||||
require_changes: false
|
require_changes: false
|
||||||
show_carryforward_flags: true
|
show_carryforward_flags: true
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/* eslint-disable no-undef */
|
/* eslint-disable no-undef */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"extends": ["plugin:playwright/playwright-test"],
|
extends: ['plugin:playwright/playwright-test'],
|
||||||
"rules": {
|
rules: {
|
||||||
"playwright/max-nested-describe": ["error", { "max": 1 }]
|
'playwright/max-nested-describe': ['error', { max: 1 }]
|
||||||
},
|
},
|
||||||
"overrides": [
|
overrides: [
|
||||||
{
|
{
|
||||||
"files": ["tests/visual/*.spec.js"],
|
files: ['tests/visual/*.spec.js'],
|
||||||
"rules": {
|
rules: {
|
||||||
"playwright/no-wait-for-timeout": "off"
|
'playwright/no-wait-for-timeout': 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -84,7 +84,7 @@ async function createDomainObjectWithDefaults(page, { type, name, parent = 'mine
|
|||||||
|
|
||||||
// Modify the name input field of the domain object to accept 'name'
|
// Modify the name input field of the domain object to accept 'name'
|
||||||
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
||||||
await nameInput.fill("");
|
await nameInput.fill('');
|
||||||
await nameInput.fill(name);
|
await nameInput.fill(name);
|
||||||
|
|
||||||
if (page.testNotes) {
|
if (page.testNotes) {
|
||||||
@ -178,7 +178,7 @@ async function createPlanFromJSON(page, { name, json, parent = 'mine' }) {
|
|||||||
|
|
||||||
// Modify the name input field of the domain object to accept 'name'
|
// Modify the name input field of the domain object to accept 'name'
|
||||||
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
||||||
await nameInput.fill("");
|
await nameInput.fill('');
|
||||||
await nameInput.fill(name);
|
await nameInput.fill(name);
|
||||||
|
|
||||||
// Upload buffer from memory
|
// Upload buffer from memory
|
||||||
@ -209,12 +209,12 @@ async function createPlanFromJSON(page, { name, json, parent = 'mine' }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the given `domainObject`'s context menu from the object tree.
|
* Open the given `domainObject`'s context menu from the object tree.
|
||||||
* Expands the path to the object and scrolls to it if necessary.
|
* Expands the path to the object and scrolls to it if necessary.
|
||||||
*
|
*
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
* @param {string} url the url to the object
|
* @param {string} url the url to the object
|
||||||
*/
|
*/
|
||||||
async function openObjectTreeContextMenu(page, url) {
|
async function openObjectTreeContextMenu(page, url) {
|
||||||
await page.goto(url);
|
await page.goto(url);
|
||||||
await page.click('button[title="Show selected item in tree"]');
|
await page.click('button[title="Show selected item in tree"]');
|
||||||
@ -228,15 +228,17 @@ async function openObjectTreeContextMenu(page, url) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
* @param {"Main Tree" | "Create Modal Tree"} [treeName="Main Tree"]
|
* @param {"Main Tree" | "Create Modal Tree"} [treeName="Main Tree"]
|
||||||
*/
|
*/
|
||||||
async function expandEntireTree(page, treeName = "Main Tree") {
|
async function expandEntireTree(page, treeName = 'Main Tree') {
|
||||||
const treeLocator = page.getByRole('tree', {
|
const treeLocator = page.getByRole('tree', {
|
||||||
name: treeName
|
name: treeName
|
||||||
});
|
});
|
||||||
const collapsedTreeItems = treeLocator.getByRole('treeitem', {
|
const collapsedTreeItems = treeLocator
|
||||||
|
.getByRole('treeitem', {
|
||||||
expanded: false
|
expanded: false
|
||||||
}).locator('span.c-disclosure-triangle.is-enabled');
|
})
|
||||||
|
.locator('span.c-disclosure-triangle.is-enabled');
|
||||||
|
|
||||||
while (await collapsedTreeItems.count() > 0) {
|
while ((await collapsedTreeItems.count()) > 0) {
|
||||||
await collapsedTreeItems.nth(0).click();
|
await collapsedTreeItems.nth(0).click();
|
||||||
|
|
||||||
// FIXME: Replace hard wait with something event-driven.
|
// FIXME: Replace hard wait with something event-driven.
|
||||||
@ -276,7 +278,10 @@ async function getHashUrlToDomainObject(page, uuid) {
|
|||||||
await page.waitForLoadState('load'); //Add some determinism
|
await page.waitForLoadState('load'); //Add some determinism
|
||||||
const hashUrl = await page.evaluate(async (objectUuid) => {
|
const hashUrl = await page.evaluate(async (objectUuid) => {
|
||||||
const path = await window.openmct.objects.getOriginalPath(objectUuid);
|
const path = await window.openmct.objects.getOriginalPath(objectUuid);
|
||||||
let url = './#/browse/' + [...path].reverse()
|
let url =
|
||||||
|
'./#/browse/' +
|
||||||
|
[...path]
|
||||||
|
.reverse()
|
||||||
.map((object) => window.openmct.objects.makeKeyString(object.identifier))
|
.map((object) => window.openmct.objects.makeKeyString(object.identifier))
|
||||||
.join('/');
|
.join('/');
|
||||||
|
|
||||||
@ -348,7 +353,7 @@ async function setRealTimeMode(page) {
|
|||||||
* @param {OffsetValues} offset
|
* @param {OffsetValues} offset
|
||||||
* @param {import('@playwright/test').Locator} offsetButton
|
* @param {import('@playwright/test').Locator} offsetButton
|
||||||
*/
|
*/
|
||||||
async function setTimeConductorOffset(page, {hours, mins, secs}, offsetButton) {
|
async function setTimeConductorOffset(page, { hours, mins, secs }, offsetButton) {
|
||||||
await offsetButton.click();
|
await offsetButton.click();
|
||||||
|
|
||||||
if (hours) {
|
if (hours) {
|
||||||
@ -407,16 +412,16 @@ async function selectInspectorTab(page, name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits and asserts that all plot series data on the page
|
* Waits and asserts that all plot series data on the page
|
||||||
* is loaded and drawn.
|
* is loaded and drawn.
|
||||||
*
|
*
|
||||||
* In lieu of a better way to detect when a plot is done rendering,
|
* In lieu of a better way to detect when a plot is done rendering,
|
||||||
* we [attach a class to the '.gl-plot' element](https://github.com/nasa/openmct/blob/5924d7ea95a0c2d4141c602a3c7d0665cb91095f/src/plugins/plot/MctPlot.vue#L27)
|
* we [attach a class to the '.gl-plot' element](https://github.com/nasa/openmct/blob/5924d7ea95a0c2d4141c602a3c7d0665cb91095f/src/plugins/plot/MctPlot.vue#L27)
|
||||||
* once all pending series data has been loaded. The following appAction retrieves
|
* once all pending series data has been loaded. The following appAction retrieves
|
||||||
* all plots on the page and waits up to the default timeout for the class to be
|
* all plots on the page and waits up to the default timeout for the class to be
|
||||||
* attached to each plot.
|
* attached to each plot.
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function waitForPlotsToRender(page) {
|
async function waitForPlotsToRender(page) {
|
||||||
const plotLocator = page.locator('.gl-plot');
|
const plotLocator = page.locator('.gl-plot');
|
||||||
for (const plot of await plotLocator.all()) {
|
for (const plot of await plotLocator.all()) {
|
||||||
@ -441,12 +446,21 @@ async function waitForPlotsToRender(page) {
|
|||||||
* @return {Promise<PlotPixel[]>}
|
* @return {Promise<PlotPixel[]>}
|
||||||
*/
|
*/
|
||||||
async function getCanvasPixels(page, canvasSelector) {
|
async function getCanvasPixels(page, canvasSelector) {
|
||||||
const getTelemValuePromise = new Promise(resolve => page.exposeFunction('getCanvasValue', resolve));
|
const getTelemValuePromise = new Promise((resolve) =>
|
||||||
const canvasHandle = await page.evaluateHandle((canvas) => document.querySelector(canvas), canvasSelector);
|
page.exposeFunction('getCanvasValue', resolve)
|
||||||
const canvasContextHandle = await page.evaluateHandle(canvas => canvas.getContext('2d'), canvasHandle);
|
);
|
||||||
|
const canvasHandle = await page.evaluateHandle(
|
||||||
|
(canvas) => document.querySelector(canvas),
|
||||||
|
canvasSelector
|
||||||
|
);
|
||||||
|
const canvasContextHandle = await page.evaluateHandle(
|
||||||
|
(canvas) => canvas.getContext('2d'),
|
||||||
|
canvasHandle
|
||||||
|
);
|
||||||
|
|
||||||
await waitForPlotsToRender(page);
|
await waitForPlotsToRender(page);
|
||||||
await page.evaluate(([canvas, ctx]) => {
|
await page.evaluate(
|
||||||
|
([canvas, ctx]) => {
|
||||||
// The document canvas is where the plot points and lines are drawn.
|
// The document canvas is where the plot points and lines are drawn.
|
||||||
// The only way to access the canvas is using document (using page.evaluate)
|
// The only way to access the canvas is using document (using page.evaluate)
|
||||||
/** @type {ImageData} */
|
/** @type {ImageData} */
|
||||||
@ -457,14 +471,16 @@ async function getCanvasPixels(page, canvasSelector) {
|
|||||||
const plotPixels = [];
|
const plotPixels = [];
|
||||||
// Each pixel consists of four values within the ImageData.data array. The for loop iterates by multiples of four.
|
// Each pixel consists of four values within the ImageData.data array. The for loop iterates by multiples of four.
|
||||||
// The values associated with each pixel are R (red), G (green), B (blue), and A (alpha), in that order.
|
// The values associated with each pixel are R (red), G (green), B (blue), and A (alpha), in that order.
|
||||||
for (let i = 0; i < imageDataValues.length;) {
|
for (let i = 0; i < imageDataValues.length; ) {
|
||||||
if (imageDataValues[i] > 0) {
|
if (imageDataValues[i] > 0) {
|
||||||
plotPixels.push({
|
plotPixels.push({
|
||||||
r: imageDataValues[i],
|
r: imageDataValues[i],
|
||||||
g: imageDataValues[i + 1],
|
g: imageDataValues[i + 1],
|
||||||
b: imageDataValues[i + 2],
|
b: imageDataValues[i + 2],
|
||||||
a: imageDataValues[i + 3],
|
a: imageDataValues[i + 3],
|
||||||
strValue: `rgb(${imageDataValues[i]}, ${imageDataValues[i + 1]}, ${imageDataValues[i + 2]}, ${imageDataValues[i + 3]})`
|
strValue: `rgb(${imageDataValues[i]}, ${imageDataValues[i + 1]}, ${
|
||||||
|
imageDataValues[i + 2]
|
||||||
|
}, ${imageDataValues[i + 3]})`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +488,9 @@ async function getCanvasPixels(page, canvasSelector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.getCanvasValue(plotPixels);
|
window.getCanvasValue(plotPixels);
|
||||||
}, [canvasHandle, canvasContextHandle]);
|
},
|
||||||
|
[canvasHandle, canvasContextHandle]
|
||||||
|
);
|
||||||
|
|
||||||
return getTelemValuePromise;
|
return getTelemValuePromise;
|
||||||
}
|
}
|
||||||
|
@ -56,12 +56,9 @@ function _consoleMessageToString(msg) {
|
|||||||
* @return {Promise<Animation[]>}
|
* @return {Promise<Animation[]>}
|
||||||
*/
|
*/
|
||||||
function waitForAnimations(locator) {
|
function waitForAnimations(locator) {
|
||||||
return locator
|
return locator.evaluate((element) =>
|
||||||
.evaluate((element) =>
|
Promise.all(element.getAnimations({ subtree: true }).map((animation) => animation.finished))
|
||||||
Promise.all(
|
);
|
||||||
element
|
|
||||||
.getAnimations({ subtree: true })
|
|
||||||
.map((animation) => animation.finished)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,7 +87,8 @@ exports.test = base.test.extend({
|
|||||||
* @see {@link https://github.com/sinonjs/fake-timers/#var-clock--faketimersinstallconfig SinonJS FakeTimers Config}
|
* @see {@link https://github.com/sinonjs/fake-timers/#var-clock--faketimersinstallconfig SinonJS FakeTimers Config}
|
||||||
*/
|
*/
|
||||||
clockOptions: [undefined, { option: true }],
|
clockOptions: [undefined, { option: true }],
|
||||||
overrideClock: [async ({ context, clockOptions }, use) => {
|
overrideClock: [
|
||||||
|
async ({ context, clockOptions }, use) => {
|
||||||
if (clockOptions !== undefined) {
|
if (clockOptions !== undefined) {
|
||||||
await context.addInitScript({
|
await context.addInitScript({
|
||||||
path: path.join(__dirname, '../', './node_modules/sinon/pkg/sinon.js')
|
path: path.join(__dirname, '../', './node_modules/sinon/pkg/sinon.js')
|
||||||
@ -101,10 +99,12 @@ exports.test = base.test.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await use(context);
|
await use(context);
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
auto: true,
|
auto: true,
|
||||||
scope: 'test'
|
scope: 'test'
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
/**
|
/**
|
||||||
* Extends the base context class to add codecoverage shim.
|
* Extends the base context class to add codecoverage shim.
|
||||||
* @see {@link https://github.com/mxschmitt/playwright-test-coverage Github Project}
|
* @see {@link https://github.com/mxschmitt/playwright-test-coverage Github Project}
|
||||||
@ -112,19 +112,24 @@ exports.test = base.test.extend({
|
|||||||
context: async ({ context }, use) => {
|
context: async ({ context }, use) => {
|
||||||
await context.addInitScript(() =>
|
await context.addInitScript(() =>
|
||||||
window.addEventListener('beforeunload', () =>
|
window.addEventListener('beforeunload', () =>
|
||||||
(window).collectIstanbulCoverage(JSON.stringify((window).__coverage__))
|
window.collectIstanbulCoverage(JSON.stringify(window.__coverage__))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
await fs.promises.mkdir(istanbulCLIOutput, { recursive: true });
|
await fs.promises.mkdir(istanbulCLIOutput, { recursive: true });
|
||||||
await context.exposeFunction('collectIstanbulCoverage', (coverageJSON) => {
|
await context.exposeFunction('collectIstanbulCoverage', (coverageJSON) => {
|
||||||
if (coverageJSON) {
|
if (coverageJSON) {
|
||||||
fs.writeFileSync(path.join(istanbulCLIOutput, `playwright_coverage_${uuid()}.json`), coverageJSON);
|
fs.writeFileSync(
|
||||||
|
path.join(istanbulCLIOutput, `playwright_coverage_${uuid()}.json`),
|
||||||
|
coverageJSON
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await use(context);
|
await use(context);
|
||||||
for (const page of context.pages()) {
|
for (const page of context.pages()) {
|
||||||
await page.evaluate(() => (window).collectIstanbulCoverage(JSON.stringify((window).__coverage__)));
|
await page.evaluate(() =>
|
||||||
|
window.collectIstanbulCoverage(JSON.stringify(window.__coverage__))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -147,8 +152,10 @@ exports.test = base.test.extend({
|
|||||||
|
|
||||||
// Assert against console errors during teardown
|
// Assert against console errors during teardown
|
||||||
if (failOnConsoleError) {
|
if (failOnConsoleError) {
|
||||||
messages.forEach(
|
messages.forEach((msg) =>
|
||||||
msg => expect.soft(msg.type(), `Console error detected: ${_consoleMessageToString(msg)}`).not.toEqual('error')
|
expect
|
||||||
|
.soft(msg.type(), `Console error detected: ${_consoleMessageToString(msg)}`)
|
||||||
|
.not.toEqual('error')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -6,8 +6,7 @@ class DomainObjectViewProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canView(domainObject) {
|
canView(domainObject) {
|
||||||
return domainObject.type === 'imageFileInput'
|
return domainObject.type === 'imageFileInput' || domainObject.type === 'jsonFileInput';
|
||||||
|| domainObject.type === 'jsonFileInput';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view(domainObject, objectPath) {
|
view(domainObject, objectPath) {
|
||||||
@ -36,7 +35,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
openmct.types.addType('jsonFileInput', {
|
openmct.types.addType('jsonFileInput', {
|
||||||
key: 'jsonFileInput',
|
key: 'jsonFileInput',
|
||||||
name: "JSON File Input Object",
|
name: 'JSON File Input Object',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
@ -46,16 +45,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
required: true,
|
required: true,
|
||||||
text: 'Select File...',
|
text: 'Select File...',
|
||||||
type: 'application/json',
|
type: 'application/json',
|
||||||
property: [
|
property: ['selectFile']
|
||||||
"selectFile"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
openmct.types.addType('imageFileInput', {
|
openmct.types.addType('imageFileInput', {
|
||||||
key: 'imageFileInput',
|
key: 'imageFileInput',
|
||||||
name: "Image File Input Object",
|
name: 'Image File Input Object',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
@ -65,9 +62,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
required: true,
|
required: true,
|
||||||
text: 'Select File...',
|
text: 'Select File...',
|
||||||
type: 'image/*',
|
type: 'image/*',
|
||||||
property: [
|
property: ['selectFile']
|
||||||
"selectFile"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -24,4 +24,4 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}());
|
})();
|
||||||
|
@ -35,7 +35,9 @@ async function navigateToFaultManagementWithExample(page) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function navigateToFaultManagementWithStaticExample(page) {
|
async function navigateToFaultManagementWithStaticExample(page) {
|
||||||
await page.addInitScript({ path: path.join(__dirname, './', 'addInitExampleFaultProviderStatic.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, './', 'addInitExampleFaultProviderStatic.js')
|
||||||
|
});
|
||||||
|
|
||||||
await navigateToFaultItemInTree(page);
|
await navigateToFaultItemInTree(page);
|
||||||
}
|
}
|
||||||
@ -55,10 +57,12 @@ async function navigateToFaultManagementWithoutExample(page) {
|
|||||||
async function navigateToFaultItemInTree(page) {
|
async function navigateToFaultItemInTree(page) {
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
const faultManagementTreeItem = page.getByRole('tree', {
|
const faultManagementTreeItem = page
|
||||||
name: "Main Tree"
|
.getByRole('tree', {
|
||||||
}).getByRole('treeitem', {
|
name: 'Main Tree'
|
||||||
name: "Fault Management"
|
})
|
||||||
|
.getByRole('treeitem', {
|
||||||
|
name: 'Fault Management'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Navigate to "Fault Management" from the tree
|
// Navigate to "Fault Management" from the tree
|
||||||
@ -73,7 +77,6 @@ async function acknowledgeFault(page, rowNumber) {
|
|||||||
await page.locator('.c-menu >> text="Acknowledge"').click();
|
await page.locator('.c-menu >> text="Acknowledge"').click();
|
||||||
// Click [aria-label="Save"]
|
// Click [aria-label="Save"]
|
||||||
await page.locator('[aria-label="Save"]').click();
|
await page.locator('[aria-label="Save"]').click();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,7 +195,9 @@ async function getFaultResultCount(page) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
function getFault(page, rowNumber) {
|
function getFault(page, rowNumber) {
|
||||||
const fault = page.locator(`.c-faults-list-view-item-body > .c-fault-mgmt__list >> nth=${rowNumber - 1}`);
|
const fault = page.locator(
|
||||||
|
`.c-faults-list-view-item-body > .c-fault-mgmt__list >> nth=${rowNumber - 1}`
|
||||||
|
);
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
@ -210,7 +215,9 @@ function getFaultByName(page, name) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function getFaultName(page, rowNumber) {
|
async function getFaultName(page, rowNumber) {
|
||||||
const faultName = await page.locator(`.c-fault-mgmt__list-faultname >> nth=${rowNumber - 1}`).textContent();
|
const faultName = await page
|
||||||
|
.locator(`.c-fault-mgmt__list-faultname >> nth=${rowNumber - 1}`)
|
||||||
|
.textContent();
|
||||||
|
|
||||||
return faultName;
|
return faultName;
|
||||||
}
|
}
|
||||||
@ -219,7 +226,9 @@ async function getFaultName(page, rowNumber) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function getFaultSeverity(page, rowNumber) {
|
async function getFaultSeverity(page, rowNumber) {
|
||||||
const faultSeverity = await page.locator(`.c-faults-list-view-item-body .c-fault-mgmt__list-severity >> nth=${rowNumber - 1}`).getAttribute('title');
|
const faultSeverity = await page
|
||||||
|
.locator(`.c-faults-list-view-item-body .c-fault-mgmt__list-severity >> nth=${rowNumber - 1}`)
|
||||||
|
.getAttribute('title');
|
||||||
|
|
||||||
return faultSeverity;
|
return faultSeverity;
|
||||||
}
|
}
|
||||||
@ -228,7 +237,9 @@ async function getFaultSeverity(page, rowNumber) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function getFaultNamespace(page, rowNumber) {
|
async function getFaultNamespace(page, rowNumber) {
|
||||||
const faultNamespace = await page.locator(`.c-fault-mgmt__list-path >> nth=${rowNumber - 1}`).textContent();
|
const faultNamespace = await page
|
||||||
|
.locator(`.c-fault-mgmt__list-path >> nth=${rowNumber - 1}`)
|
||||||
|
.textContent();
|
||||||
|
|
||||||
return faultNamespace;
|
return faultNamespace;
|
||||||
}
|
}
|
||||||
@ -237,7 +248,9 @@ async function getFaultNamespace(page, rowNumber) {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function getFaultTriggerTime(page, rowNumber) {
|
async function getFaultTriggerTime(page, rowNumber) {
|
||||||
const faultTriggerTime = await page.locator(`.c-fault-mgmt__list-trigTime >> nth=${rowNumber - 1} >> .c-fault-mgmt-item__value`).textContent();
|
const faultTriggerTime = await page
|
||||||
|
.locator(`.c-fault-mgmt__list-trigTime >> nth=${rowNumber - 1} >> .c-fault-mgmt-item__value`)
|
||||||
|
.textContent();
|
||||||
|
|
||||||
return faultTriggerTime.toString().trim();
|
return faultTriggerTime.toString().trim();
|
||||||
}
|
}
|
||||||
@ -247,8 +260,9 @@ async function getFaultTriggerTime(page, rowNumber) {
|
|||||||
*/
|
*/
|
||||||
async function openFaultRowMenu(page, rowNumber) {
|
async function openFaultRowMenu(page, rowNumber) {
|
||||||
// select
|
// select
|
||||||
await page.locator(`.c-fault-mgmt-item > .c-fault-mgmt__list-action-button >> nth=${rowNumber - 1}`).click();
|
await page
|
||||||
|
.locator(`.c-fault-mgmt-item > .c-fault-mgmt__list-action-button >> nth=${rowNumber - 1}`)
|
||||||
|
.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
|
@ -42,7 +42,7 @@ async function enterTextEntry(page, text) {
|
|||||||
async function dragAndDropEmbed(page, notebookObject) {
|
async function dragAndDropEmbed(page, notebookObject) {
|
||||||
// Create example telemetry object
|
// Create example telemetry object
|
||||||
const swg = await createDomainObjectWithDefaults(page, {
|
const swg = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator"
|
type: 'Sine Wave Generator'
|
||||||
});
|
});
|
||||||
// Navigate to notebook
|
// Navigate to notebook
|
||||||
await page.goto(notebookObject.url);
|
await page.goto(notebookObject.url);
|
||||||
|
@ -46,32 +46,39 @@ export async function assertPlanActivities(page, plan, objectUrl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Switch to fixed time mode with all plan events within the bounds
|
// Switch to fixed time mode with all plan events within the bounds
|
||||||
await page.goto(`${objectUrl}?tc.mode=fixed&tc.startBound=${startBound}&tc.endBound=${endBound}&tc.timeSystem=utc&view=plan.view`);
|
await page.goto(
|
||||||
|
`${objectUrl}?tc.mode=fixed&tc.startBound=${startBound}&tc.endBound=${endBound}&tc.timeSystem=utc&view=plan.view`
|
||||||
|
);
|
||||||
|
|
||||||
// Assert that the number of activities in the plan view matches the number of
|
// Assert that the number of activities in the plan view matches the number of
|
||||||
// activities in the plan data within the specified time bounds
|
// activities in the plan data within the specified time bounds
|
||||||
const eventCount = await page.locator('.activity-bounds').count();
|
const eventCount = await page.locator('.activity-bounds').count();
|
||||||
expect(eventCount).toEqual(Object.values(plan)
|
expect(eventCount).toEqual(
|
||||||
|
Object.values(plan)
|
||||||
.flat()
|
.flat()
|
||||||
.filter(event =>
|
.filter((event) =>
|
||||||
activitiesWithinTimeBounds(event.start, event.end, startBound, endBound)).length);
|
activitiesWithinTimeBounds(event.start, event.end, startBound, endBound)
|
||||||
|
).length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the activities time bounds overlap, false otherwise.
|
* Returns true if the activities time bounds overlap, false otherwise.
|
||||||
* @param {number} start1 the start time of the first activity
|
* @param {number} start1 the start time of the first activity
|
||||||
* @param {number} end1 the end time of the first activity
|
* @param {number} end1 the end time of the first activity
|
||||||
* @param {number} start2 the start time of the second activity
|
* @param {number} start2 the start time of the second activity
|
||||||
* @param {number} end2 the end time of the second activity
|
* @param {number} end2 the end time of the second activity
|
||||||
* @returns {boolean} true if the activities overlap, false otherwise
|
* @returns {boolean} true if the activities overlap, false otherwise
|
||||||
*/
|
*/
|
||||||
function activitiesWithinTimeBounds(start1, end1, start2, end2) {
|
function activitiesWithinTimeBounds(start1, end1, start2, end2) {
|
||||||
return (start1 >= start2 && start1 <= end2)
|
return (
|
||||||
|| (end1 >= start2 && end1 <= end2)
|
(start1 >= start2 && start1 <= end2) ||
|
||||||
|| (start2 >= start1 && start2 <= end1)
|
(end1 >= start2 && end1 <= end2) ||
|
||||||
|| (end2 >= start1 && end2 <= end1);
|
(start2 >= start1 && start2 <= end1) ||
|
||||||
|
(end2 >= start1 && end2 <= end1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,9 +91,11 @@ function activitiesWithinTimeBounds(start1, end1, start2, end2) {
|
|||||||
export async function setBoundsToSpanAllActivities(page, planJson, planObjectUrl) {
|
export async function setBoundsToSpanAllActivities(page, planJson, planObjectUrl) {
|
||||||
const activities = Object.values(planJson).flat();
|
const activities = Object.values(planJson).flat();
|
||||||
// Get the earliest start value
|
// Get the earliest start value
|
||||||
const start = Math.min(...activities.map(activity => activity.start));
|
const start = Math.min(...activities.map((activity) => activity.start));
|
||||||
// Get the latest end value
|
// Get the latest end value
|
||||||
const end = Math.max(...activities.map(activity => activity.end));
|
const end = Math.max(...activities.map((activity) => activity.end));
|
||||||
// Set the start and end bounds to the earliest start and latest end
|
// Set the start and end bounds to the earliest start and latest end
|
||||||
await page.goto(`${planObjectUrl}?tc.mode=fixed&tc.startBound=${start}&tc.endBound=${end}&tc.timeSystem=utc&view=plan.view`);
|
await page.goto(
|
||||||
|
`${planObjectUrl}?tc.mode=fixed&tc.startBound=${start}&tc.endBound=${end}&tc.timeSystem=utc&view=plan.view`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -69,10 +69,13 @@ const config = {
|
|||||||
],
|
],
|
||||||
reporter: [
|
reporter: [
|
||||||
['list'],
|
['list'],
|
||||||
['html', {
|
[
|
||||||
|
'html',
|
||||||
|
{
|
||||||
open: 'never',
|
open: 'never',
|
||||||
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
['junit', { outputFile: '../test-results/results.xml' }],
|
['junit', { outputFile: '../test-results/results.xml' }],
|
||||||
['github'],
|
['github'],
|
||||||
['@deploysentinel/playwright']
|
['@deploysentinel/playwright']
|
||||||
|
@ -19,7 +19,7 @@ const config = {
|
|||||||
},
|
},
|
||||||
workers: 1,
|
workers: 1,
|
||||||
use: {
|
use: {
|
||||||
browserName: "chromium",
|
browserName: 'chromium',
|
||||||
baseURL: 'http://localhost:8080/',
|
baseURL: 'http://localhost:8080/',
|
||||||
headless: false,
|
headless: false,
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
@ -94,10 +94,13 @@ const config = {
|
|||||||
],
|
],
|
||||||
reporter: [
|
reporter: [
|
||||||
['list'],
|
['list'],
|
||||||
['html', {
|
[
|
||||||
|
'html',
|
||||||
|
{
|
||||||
open: 'on-failure',
|
open: 'on-failure',
|
||||||
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ const config = {
|
|||||||
reuseExistingServer: !CI
|
reuseExistingServer: !CI
|
||||||
},
|
},
|
||||||
use: {
|
use: {
|
||||||
browserName: "chromium",
|
browserName: 'chromium',
|
||||||
baseURL: 'http://localhost:8080/',
|
baseURL: 'http://localhost:8080/',
|
||||||
headless: CI, //Only if running locally
|
headless: CI, //Only if running locally
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
|
@ -41,10 +41,13 @@ const config = {
|
|||||||
reporter: [
|
reporter: [
|
||||||
['list'],
|
['list'],
|
||||||
['junit', { outputFile: '../test-results/results.xml' }],
|
['junit', { outputFile: '../test-results/results.xml' }],
|
||||||
['html', {
|
[
|
||||||
|
'html',
|
||||||
|
{
|
||||||
open: 'on-failure',
|
open: 'on-failure',
|
||||||
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ const theme = 'espresso';
|
|||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
const myItemsFolderName = "My Items";
|
const myItemsFolderName = 'My Items';
|
||||||
|
|
||||||
exports.test = test.extend({
|
exports.test = test.extend({
|
||||||
// This should follow in the Project's configuration. Can be set to 'snow' in playwright config.js
|
// This should follow in the Project's configuration. Can be set to 'snow' in playwright config.js
|
||||||
@ -136,10 +136,7 @@ exports.test = test.extend({
|
|||||||
// Attach info about the currently running test and its project.
|
// Attach info about the currently running test and its project.
|
||||||
// This will be used by appActions to fill in the created
|
// This will be used by appActions to fill in the created
|
||||||
// domain object's notes.
|
// domain object's notes.
|
||||||
page.testNotes = [
|
page.testNotes = [`${testInfo.titlePath.join('\n')}`, `${testInfo.project.name}`].join('\n');
|
||||||
`${testInfo.titlePath.join('\n')}`,
|
|
||||||
`${testInfo.project.name}`
|
|
||||||
].join('\n');
|
|
||||||
|
|
||||||
await use(page);
|
await use(page);
|
||||||
},
|
},
|
||||||
|
@ -274,10 +274,7 @@
|
|||||||
"id": "ac0d7eb1-b485-458f-bd2a-a63aa87a3a8a"
|
"id": "ac0d7eb1-b485-458f-bd2a-a63aa87a3a8a"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"layoutGrid": [
|
"layoutGrid": [10, 10],
|
||||||
10,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"objectStyles": {
|
"objectStyles": {
|
||||||
"ed63cc29-80e2-4e2b-a472-3d6d4adbf310": {
|
"ed63cc29-80e2-4e2b-a472-3d6d4adbf310": {
|
||||||
"staticStyle": {
|
"staticStyle": {
|
||||||
@ -1455,9 +1452,7 @@
|
|||||||
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "greaterThan",
|
"operation": "greaterThan",
|
||||||
"input": [
|
"input": ["120"],
|
||||||
"120"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1475,10 +1470,7 @@
|
|||||||
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "between",
|
"operation": "between",
|
||||||
"input": [
|
"input": ["120", "-20"],
|
||||||
"120",
|
|
||||||
"-20"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1496,9 +1488,7 @@
|
|||||||
"id": "6707be12-6a6e-4535-bb97-ab5c86f99934",
|
"id": "6707be12-6a6e-4535-bb97-ab5c86f99934",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "lessThan",
|
"operation": "lessThan",
|
||||||
"input": [
|
"input": ["-20"],
|
||||||
"-20"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1550,9 +1540,7 @@
|
|||||||
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "greaterThan",
|
"operation": "greaterThan",
|
||||||
"input": [
|
"input": ["120"],
|
||||||
"120"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1570,10 +1558,7 @@
|
|||||||
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "between",
|
"operation": "between",
|
||||||
"input": [
|
"input": ["120", "-20"],
|
||||||
"120",
|
|
||||||
"-20"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1591,9 +1576,7 @@
|
|||||||
"id": "6707be12-6a6e-4535-bb97-ab5c86f99934",
|
"id": "6707be12-6a6e-4535-bb97-ab5c86f99934",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "lessThan",
|
"operation": "lessThan",
|
||||||
"input": [
|
"input": ["-20"],
|
||||||
"-20"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1645,9 +1628,7 @@
|
|||||||
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "greaterThan",
|
"operation": "greaterThan",
|
||||||
"input": [
|
"input": ["150"],
|
||||||
"150"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1665,10 +1646,7 @@
|
|||||||
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "between",
|
"operation": "between",
|
||||||
"input": [
|
"input": ["50", "-50"],
|
||||||
"50",
|
|
||||||
"-50"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1720,9 +1698,7 @@
|
|||||||
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
"id": "64e49fe7-5b36-43db-8347-4550b910de4c",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "greaterThan",
|
"operation": "greaterThan",
|
||||||
"input": [
|
"input": ["150"],
|
||||||
"150"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -1740,10 +1716,7 @@
|
|||||||
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
"id": "59f1c4bf-5d36-450c-9668-6546955fc066",
|
||||||
"telemetry": "any",
|
"telemetry": "any",
|
||||||
"operation": "between",
|
"operation": "between",
|
||||||
"input": [
|
"input": ["50", "-50"],
|
||||||
"50",
|
|
||||||
"-50"
|
|
||||||
],
|
|
||||||
"metadata": "sin"
|
"metadata": "sin"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1 +1,90 @@
|
|||||||
{"openmct":{"b3cee102-86dd-4c0a-8eec-4d5d276f8691":{"identifier":{"key":"b3cee102-86dd-4c0a-8eec-4d5d276f8691","namespace":""},"name":"Performance Display Layout","type":"layout","composition":[{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""}],"configuration":{"items":[{"width":32,"height":18,"x":12,"y":9,"identifier":{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""},"hasFrame":true,"fontSize":"default","font":"default","type":"subobject-view","id":"23ca351d-a67d-46aa-a762-290eb742d2f1"}],"layoutGrid":[10,10]},"modified":1654299875432,"location":"mine","persisted":1654299878751},"9666e7b4-be0c-47a5-94b8-99accad7155e":{"identifier":{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""},"name":"Performance Example Imagery","type":"example.imagery","configuration":{"imageLocation":"","imageLoadDelayInMilliSeconds":20000,"imageSamples":[],"layers":[{"source":"dist/imagery/example-imagery-layer-16x9.png","name":"16:9","visible":false},{"source":"dist/imagery/example-imagery-layer-safe.png","name":"Safe","visible":false},{"source":"dist/imagery/example-imagery-layer-scale.png","name":"Scale","visible":false}]},"telemetry":{"values":[{"name":"Name","key":"name"},{"name":"Time","key":"utc","format":"utc","hints":{"domain":2}},{"name":"Local Time","key":"local","format":"local-format","hints":{"domain":1}},{"name":"Image","key":"url","format":"image","hints":{"image":1},"layers":[{"source":"dist/imagery/example-imagery-layer-16x9.png","name":"16:9"},{"source":"dist/imagery/example-imagery-layer-safe.png","name":"Safe"},{"source":"dist/imagery/example-imagery-layer-scale.png","name":"Scale"}]},{"name":"Image Download Name","key":"imageDownloadName","format":"imageDownloadName","hints":{"imageDownloadName":1}}]},"modified":1654299840077,"location":"b3cee102-86dd-4c0a-8eec-4d5d276f8691","persisted":1654299840078}},"rootId":"b3cee102-86dd-4c0a-8eec-4d5d276f8691"}
|
{
|
||||||
|
"openmct": {
|
||||||
|
"b3cee102-86dd-4c0a-8eec-4d5d276f8691": {
|
||||||
|
"identifier": { "key": "b3cee102-86dd-4c0a-8eec-4d5d276f8691", "namespace": "" },
|
||||||
|
"name": "Performance Display Layout",
|
||||||
|
"type": "layout",
|
||||||
|
"composition": [{ "key": "9666e7b4-be0c-47a5-94b8-99accad7155e", "namespace": "" }],
|
||||||
|
"configuration": {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"width": 32,
|
||||||
|
"height": 18,
|
||||||
|
"x": 12,
|
||||||
|
"y": 9,
|
||||||
|
"identifier": { "key": "9666e7b4-be0c-47a5-94b8-99accad7155e", "namespace": "" },
|
||||||
|
"hasFrame": true,
|
||||||
|
"fontSize": "default",
|
||||||
|
"font": "default",
|
||||||
|
"type": "subobject-view",
|
||||||
|
"id": "23ca351d-a67d-46aa-a762-290eb742d2f1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"layoutGrid": [10, 10]
|
||||||
|
},
|
||||||
|
"modified": 1654299875432,
|
||||||
|
"location": "mine",
|
||||||
|
"persisted": 1654299878751
|
||||||
|
},
|
||||||
|
"9666e7b4-be0c-47a5-94b8-99accad7155e": {
|
||||||
|
"identifier": { "key": "9666e7b4-be0c-47a5-94b8-99accad7155e", "namespace": "" },
|
||||||
|
"name": "Performance Example Imagery",
|
||||||
|
"type": "example.imagery",
|
||||||
|
"configuration": {
|
||||||
|
"imageLocation": "",
|
||||||
|
"imageLoadDelayInMilliSeconds": 20000,
|
||||||
|
"imageSamples": [],
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"source": "dist/imagery/example-imagery-layer-16x9.png",
|
||||||
|
"name": "16:9",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "dist/imagery/example-imagery-layer-safe.png",
|
||||||
|
"name": "Safe",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "dist/imagery/example-imagery-layer-scale.png",
|
||||||
|
"name": "Scale",
|
||||||
|
"visible": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"telemetry": {
|
||||||
|
"values": [
|
||||||
|
{ "name": "Name", "key": "name" },
|
||||||
|
{ "name": "Time", "key": "utc", "format": "utc", "hints": { "domain": 2 } },
|
||||||
|
{
|
||||||
|
"name": "Local Time",
|
||||||
|
"key": "local",
|
||||||
|
"format": "local-format",
|
||||||
|
"hints": { "domain": 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image",
|
||||||
|
"key": "url",
|
||||||
|
"format": "image",
|
||||||
|
"hints": { "image": 1 },
|
||||||
|
"layers": [
|
||||||
|
{ "source": "dist/imagery/example-imagery-layer-16x9.png", "name": "16:9" },
|
||||||
|
{ "source": "dist/imagery/example-imagery-layer-safe.png", "name": "Safe" },
|
||||||
|
{ "source": "dist/imagery/example-imagery-layer-scale.png", "name": "Scale" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image Download Name",
|
||||||
|
"key": "imageDownloadName",
|
||||||
|
"format": "imageDownloadName",
|
||||||
|
"hints": { "imageDownloadName": 1 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modified": 1654299840077,
|
||||||
|
"location": "b3cee102-86dd-4c0a-8eec-4d5d276f8691",
|
||||||
|
"persisted": 1654299840078
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rootId": "b3cee102-86dd-4c0a-8eec-4d5d276f8691"
|
||||||
|
}
|
||||||
|
@ -1 +1,96 @@
|
|||||||
{"openmct":{"6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d":{"identifier":{"key":"6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d","namespace":""},"name":"Performance Notebook","type":"notebook","configuration":{"defaultSort":"oldest","entries":{"3e31c412-33ba-4757-8ade-e9821f6ba321":{"8c8f6035-631c-45af-8c24-786c60295335":[{"id":"entry-1652815305457","createdOn":1652815305457,"createdBy":"","text":"Existing Entry 1","embeds":[]},{"id":"entry-1652815313465","createdOn":1652815313465,"createdBy":"","text":"Existing Entry 2","embeds":[]},{"id":"entry-1652815399955","createdOn":1652815399955,"createdBy":"","text":"Existing Entry 3","embeds":[]}]}},"imageMigrationVer":"v1","pageTitle":"Page","sections":[{"id":"3e31c412-33ba-4757-8ade-e9821f6ba321","isDefault":false,"isSelected":false,"name":"Section1","pages":[{"id":"8c8f6035-631c-45af-8c24-786c60295335","isDefault":false,"isSelected":false,"name":"Page1","pageTitle":"Page"},{"id":"36555942-c9aa-439c-bbdb-0aaf50db50f5","isDefault":false,"isSelected":false,"name":"Page2","pageTitle":"Page"}],"sectionTitle":"Section"},{"id":"dab0bd1d-2c5a-405c-987f-107123d6189a","isDefault":false,"isSelected":true,"name":"Section2","pages":[{"id":"f625a86a-cb99-4898-8082-80543c8de534","isDefault":false,"isSelected":false,"name":"Page1","pageTitle":"Page"},{"id":"e77ef810-f785-42a7-942e-07e999b79c59","isDefault":false,"isSelected":true,"name":"Page2","pageTitle":"Page"}],"sectionTitle":"Section"}],"sectionTitle":"Section","type":"General","showTime":"0"},"modified":1652815915219,"location":"mine","persisted":1652815915222}},"rootId":"6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d"}
|
{
|
||||||
|
"openmct": {
|
||||||
|
"6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d": {
|
||||||
|
"identifier": { "key": "6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d", "namespace": "" },
|
||||||
|
"name": "Performance Notebook",
|
||||||
|
"type": "notebook",
|
||||||
|
"configuration": {
|
||||||
|
"defaultSort": "oldest",
|
||||||
|
"entries": {
|
||||||
|
"3e31c412-33ba-4757-8ade-e9821f6ba321": {
|
||||||
|
"8c8f6035-631c-45af-8c24-786c60295335": [
|
||||||
|
{
|
||||||
|
"id": "entry-1652815305457",
|
||||||
|
"createdOn": 1652815305457,
|
||||||
|
"createdBy": "",
|
||||||
|
"text": "Existing Entry 1",
|
||||||
|
"embeds": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "entry-1652815313465",
|
||||||
|
"createdOn": 1652815313465,
|
||||||
|
"createdBy": "",
|
||||||
|
"text": "Existing Entry 2",
|
||||||
|
"embeds": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "entry-1652815399955",
|
||||||
|
"createdOn": 1652815399955,
|
||||||
|
"createdBy": "",
|
||||||
|
"text": "Existing Entry 3",
|
||||||
|
"embeds": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imageMigrationVer": "v1",
|
||||||
|
"pageTitle": "Page",
|
||||||
|
"sections": [
|
||||||
|
{
|
||||||
|
"id": "3e31c412-33ba-4757-8ade-e9821f6ba321",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": false,
|
||||||
|
"name": "Section1",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"id": "8c8f6035-631c-45af-8c24-786c60295335",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": false,
|
||||||
|
"name": "Page1",
|
||||||
|
"pageTitle": "Page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "36555942-c9aa-439c-bbdb-0aaf50db50f5",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": false,
|
||||||
|
"name": "Page2",
|
||||||
|
"pageTitle": "Page"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sectionTitle": "Section"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "dab0bd1d-2c5a-405c-987f-107123d6189a",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": true,
|
||||||
|
"name": "Section2",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"id": "f625a86a-cb99-4898-8082-80543c8de534",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": false,
|
||||||
|
"name": "Page1",
|
||||||
|
"pageTitle": "Page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e77ef810-f785-42a7-942e-07e999b79c59",
|
||||||
|
"isDefault": false,
|
||||||
|
"isSelected": true,
|
||||||
|
"name": "Page2",
|
||||||
|
"pageTitle": "Page"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sectionTitle": "Section"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sectionTitle": "Section",
|
||||||
|
"type": "General",
|
||||||
|
"showTime": "0"
|
||||||
|
},
|
||||||
|
"modified": 1652815915219,
|
||||||
|
"location": "mine",
|
||||||
|
"persisted": 1652815915222
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rootId": "6d2fa9fd-f2aa-461a-a1e1-164ac44bec9d"
|
||||||
|
}
|
||||||
|
@ -21,7 +21,11 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../pluginFixtures.js');
|
const { test, expect } = require('../../pluginFixtures.js');
|
||||||
const { createDomainObjectWithDefaults, createNotification, expandEntireTree } = require('../../appActions.js');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
createNotification,
|
||||||
|
expandEntireTree
|
||||||
|
} = require('../../appActions.js');
|
||||||
|
|
||||||
test.describe('AppActions', () => {
|
test.describe('AppActions', () => {
|
||||||
test('createDomainObjectsWithDefaults', async ({ page }) => {
|
test('createDomainObjectsWithDefaults', async ({ page }) => {
|
||||||
@ -85,7 +89,7 @@ test.describe('AppActions', () => {
|
|||||||
expect(folder3.url).toBe(`${e2eFolder.url}/${folder1.uuid}/${folder2.uuid}/${folder3.uuid}`);
|
expect(folder3.url).toBe(`${e2eFolder.url}/${folder1.uuid}/${folder2.uuid}/${folder3.uuid}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test("createNotification", async ({ page }) => {
|
test('createNotification', async ({ page }) => {
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
await createNotification(page, {
|
await createNotification(page, {
|
||||||
message: 'Test info notification',
|
message: 'Test info notification',
|
||||||
@ -144,7 +148,7 @@ test.describe('AppActions', () => {
|
|||||||
await page.goto('./#/browse/mine');
|
await page.goto('./#/browse/mine');
|
||||||
await expandEntireTree(page);
|
await expandEntireTree(page);
|
||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: "Main Tree"
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
const treePaneCollapsedItems = treePane.getByRole('treeitem', { expanded: false });
|
const treePaneCollapsedItems = treePane.getByRole('treeitem', { expanded: false });
|
||||||
expect(await treePaneCollapsedItems.count()).toBe(0);
|
expect(await treePaneCollapsedItems.count()).toBe(0);
|
||||||
@ -155,9 +159,9 @@ test.describe('AppActions', () => {
|
|||||||
|
|
||||||
// Click the object specified by 'type'
|
// Click the object specified by 'type'
|
||||||
await page.click(`li[role='menuitem']:text("Clock")`);
|
await page.click(`li[role='menuitem']:text("Clock")`);
|
||||||
await expandEntireTree(page, "Create Modal Tree");
|
await expandEntireTree(page, 'Create Modal Tree');
|
||||||
const locatorTree = page.getByRole("tree", {
|
const locatorTree = page.getByRole('tree', {
|
||||||
name: "Create Modal Tree"
|
name: 'Create Modal Tree'
|
||||||
});
|
});
|
||||||
const locatorTreeCollapsedItems = locatorTree.locator('role=treeitem[expanded=false]');
|
const locatorTreeCollapsedItems = locatorTree.locator('role=treeitem[expanded=false]');
|
||||||
expect(await locatorTreeCollapsedItems.count()).toBe(0);
|
expect(await locatorTreeCollapsedItems.count()).toBe(0);
|
||||||
|
@ -39,7 +39,6 @@ test.describe('baseFixtures tests', () => {
|
|||||||
page.evaluate(() => console.error('This should result in a failure')),
|
page.evaluate(() => console.error('This should result in a failure')),
|
||||||
page.waitForEvent('console') // always wait for the event to happen while triggering it!
|
page.waitForEvent('console') // always wait for the event to happen while triggering it!
|
||||||
]);
|
]);
|
||||||
|
|
||||||
});
|
});
|
||||||
test('Verify that tests pass if console.warn is thrown', async ({ page }) => {
|
test('Verify that tests pass if console.warn is thrown', async ({ page }) => {
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
@ -50,6 +49,5 @@ test.describe('baseFixtures tests', () => {
|
|||||||
page.evaluate(() => console.warn('This should result in a pass')),
|
page.evaluate(() => console.warn('This should result in a pass')),
|
||||||
page.waitForEvent('console') // always wait for the event to happen while triggering it!
|
page.waitForEvent('console') // always wait for the event to happen while triggering it!
|
||||||
]);
|
]);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,28 +21,28 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite template is to be used when creating new test suites. It will be kept up to date with the latest improvements
|
* This test suite template is to be used when creating new test suites. It will be kept up to date with the latest improvements
|
||||||
* made by the Open MCT team. It will also follow our best pratices as those evolve. Please use this structure as a _reference_ and clear
|
* made by the Open MCT team. It will also follow our best pratices as those evolve. Please use this structure as a _reference_ and clear
|
||||||
* or update any references when creating a new test suite!
|
* or update any references when creating a new test suite!
|
||||||
*
|
*
|
||||||
* To illustrate current best practices, we've included a mocked up test suite for Renaming a Timer domain object.
|
* To illustrate current best practices, we've included a mocked up test suite for Renaming a Timer domain object.
|
||||||
*
|
*
|
||||||
* Demonstrated:
|
* Demonstrated:
|
||||||
* - Using appActions to leverage existing functions
|
* - Using appActions to leverage existing functions
|
||||||
* - Structure
|
* - Structure
|
||||||
* - @unstable annotation
|
* - @unstable annotation
|
||||||
* - await, expect, test, describe syntax
|
* - await, expect, test, describe syntax
|
||||||
* - Writing a custom function for a test suite
|
* - Writing a custom function for a test suite
|
||||||
* - Test stub for unfinished test coverage (test.fixme)
|
* - Test stub for unfinished test coverage (test.fixme)
|
||||||
*
|
*
|
||||||
* The structure should follow
|
* The structure should follow
|
||||||
* 1. imports
|
* 1. imports
|
||||||
* 2. test.describe()
|
* 2. test.describe()
|
||||||
* 3. -> test1
|
* 3. -> test1
|
||||||
* -> test2
|
* -> test2
|
||||||
* -> test3(stub)
|
* -> test3(stub)
|
||||||
* 4. Any custom functions
|
* 4. Any custom functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Structure: Some standard Imports. Please update the required pathing.
|
// Structure: Some standard Imports. Please update the required pathing.
|
||||||
const { test, expect } = require('../../pluginFixtures');
|
const { test, expect } = require('../../pluginFixtures');
|
||||||
@ -79,7 +79,7 @@ test.describe('Renaming Timer Object', () => {
|
|||||||
* some hint as to what went wrong if the test fails.
|
* some hint as to what went wrong if the test fails.
|
||||||
*/
|
*/
|
||||||
test('An existing Timer object can be renamed via the 3dot actions menu', async ({ page }) => {
|
test('An existing Timer object can be renamed via the 3dot actions menu', async ({ page }) => {
|
||||||
const newObjectName = "Renamed Timer";
|
const newObjectName = 'Renamed Timer';
|
||||||
|
|
||||||
// We've created an example of a shared function which pases the page and newObjectName values
|
// We've created an example of a shared function which pases the page and newObjectName values
|
||||||
await renameTimerFrom3DotMenu(page, timer.url, newObjectName);
|
await renameTimerFrom3DotMenu(page, timer.url, newObjectName);
|
||||||
@ -89,8 +89,8 @@ test.describe('Renaming Timer Object', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('An existing Timer object can be renamed twice', async ({ page }) => {
|
test('An existing Timer object can be renamed twice', async ({ page }) => {
|
||||||
const newObjectName = "Renamed Timer";
|
const newObjectName = 'Renamed Timer';
|
||||||
const newObjectName2 = "Re-Renamed Timer";
|
const newObjectName2 = 'Re-Renamed Timer';
|
||||||
|
|
||||||
await renameTimerFrom3DotMenu(page, timer.url, newObjectName);
|
await renameTimerFrom3DotMenu(page, timer.url, newObjectName);
|
||||||
|
|
||||||
|
@ -31,14 +31,12 @@ const { test } = require('../../pluginFixtures.js');
|
|||||||
test.describe.skip('pluginFixtures tests', () => {
|
test.describe.skip('pluginFixtures tests', () => {
|
||||||
// test.use({ domainObjectName: 'Timer' });
|
// test.use({ domainObjectName: 'Timer' });
|
||||||
// let timerUUID;
|
// let timerUUID;
|
||||||
|
|
||||||
// test('Creates a timer object @framework @unstable', ({ domainObject }) => {
|
// test('Creates a timer object @framework @unstable', ({ domainObject }) => {
|
||||||
// const { uuid } = domainObject;
|
// const { uuid } = domainObject;
|
||||||
// const uuidRegexp = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/;
|
// const uuidRegexp = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/;
|
||||||
// expect(uuid).toMatch(uuidRegexp);
|
// expect(uuid).toMatch(uuidRegexp);
|
||||||
// timerUUID = uuid;
|
// timerUUID = uuid;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// test('Provides same uuid for subsequent uses of the same object @framework', ({ domainObject }) => {
|
// test('Provides same uuid for subsequent uses of the same object @framework', ({ domainObject }) => {
|
||||||
// const { uuid } = domainObject;
|
// const { uuid } = domainObject;
|
||||||
// expect(uuid).toEqual(timerUUID);
|
// expect(uuid).toEqual(timerUUID);
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite template is to be used when verifying Test Data files found in /e2e/test-data/
|
* This test suite template is to be used when verifying Test Data files found in /e2e/test-data/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test } = require('../../baseFixtures');
|
const { test } = require('../../baseFixtures');
|
||||||
|
|
||||||
@ -33,4 +33,3 @@ test.describe('recycled_local_storage @localStorage', () => {
|
|||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,7 +41,9 @@ test.describe('Branding tests', () => {
|
|||||||
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
||||||
await expect(versionInformationLocator).toBeEnabled();
|
await expect(versionInformationLocator).toBeEnabled();
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Version: \d/);
|
await expect.soft(versionInformationLocator).toContainText(/Version: \d/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Build Date: ((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun))/);
|
await expect
|
||||||
|
.soft(versionInformationLocator)
|
||||||
|
.toContainText(/Build Date: ((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun))/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
await expect.soft(versionInformationLocator).toContainText(/Revision: \b[0-9a-f]{5,40}\b/);
|
||||||
await expect.soft(versionInformationLocator).toContainText(/Branch: ./);
|
await expect.soft(versionInformationLocator).toContainText(/Branch: ./);
|
||||||
});
|
});
|
||||||
|
@ -21,17 +21,17 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite is meant to be executed against a couchdb container. More doc to come
|
* This test suite is meant to be executed against a couchdb container. More doc to come
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../pluginFixtures');
|
const { test, expect } = require('../../pluginFixtures');
|
||||||
|
|
||||||
test.describe("CouchDB Status Indicator with mocked responses @couchdb", () => {
|
test.describe('CouchDB Status Indicator with mocked responses @couchdb', () => {
|
||||||
test.use({ failOnConsoleError: false });
|
test.use({ failOnConsoleError: false });
|
||||||
//TODO BeforeAll Verify CouchDB Connectivity with APIContext
|
//TODO BeforeAll Verify CouchDB Connectivity with APIContext
|
||||||
test('Shows green if connected', async ({ page }) => {
|
test('Shows green if connected', async ({ page }) => {
|
||||||
await page.route('**/openmct/mine', route => {
|
await page.route('**/openmct/mine', (route) => {
|
||||||
route.fulfill({
|
route.fulfill({
|
||||||
status: 200,
|
status: 200,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
@ -40,11 +40,13 @@ test.describe("CouchDB Status Indicator with mocked responses @couchdb", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { waitUntil: 'networkidle' });
|
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', {
|
||||||
|
waitUntil: 'networkidle'
|
||||||
|
});
|
||||||
await expect(page.locator('div:has-text("CouchDB is connected")').nth(3)).toBeVisible();
|
await expect(page.locator('div:has-text("CouchDB is connected")').nth(3)).toBeVisible();
|
||||||
});
|
});
|
||||||
test('Shows red if not connected', async ({ page }) => {
|
test('Shows red if not connected', async ({ page }) => {
|
||||||
await page.route('**/openmct/**', route => {
|
await page.route('**/openmct/**', (route) => {
|
||||||
route.fulfill({
|
route.fulfill({
|
||||||
status: 503,
|
status: 503,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
@ -53,11 +55,13 @@ test.describe("CouchDB Status Indicator with mocked responses @couchdb", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { waitUntil: 'networkidle' });
|
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', {
|
||||||
|
waitUntil: 'networkidle'
|
||||||
|
});
|
||||||
await expect(page.locator('div:has-text("CouchDB is offline")').nth(3)).toBeVisible();
|
await expect(page.locator('div:has-text("CouchDB is offline")').nth(3)).toBeVisible();
|
||||||
});
|
});
|
||||||
test('Shows unknown if it receives an unexpected response code', async ({ page }) => {
|
test('Shows unknown if it receives an unexpected response code', async ({ page }) => {
|
||||||
await page.route('**/openmct/mine', route => {
|
await page.route('**/openmct/mine', (route) => {
|
||||||
route.fulfill({
|
route.fulfill({
|
||||||
status: 418,
|
status: 418,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
@ -66,12 +70,14 @@ test.describe("CouchDB Status Indicator with mocked responses @couchdb", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', { waitUntil: 'networkidle' });
|
await page.goto('./#/browse/mine?hideTree=true&hideInspector=true', {
|
||||||
|
waitUntil: 'networkidle'
|
||||||
|
});
|
||||||
await expect(page.locator('div:has-text("CouchDB connectivity unknown")').nth(3)).toBeVisible();
|
await expect(page.locator('div:has-text("CouchDB connectivity unknown")').nth(3)).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe("CouchDB initialization with mocked responses @couchdb", () => {
|
test.describe('CouchDB initialization with mocked responses @couchdb', () => {
|
||||||
test.use({ failOnConsoleError: false });
|
test.use({ failOnConsoleError: false });
|
||||||
test("'My Items' folder is created if it doesn't exist", async ({ page }) => {
|
test("'My Items' folder is created if it doesn't exist", async ({ page }) => {
|
||||||
const mockedMissingObjectResponsefromCouchDB = {
|
const mockedMissingObjectResponsefromCouchDB = {
|
||||||
@ -83,29 +89,30 @@ test.describe("CouchDB initialization with mocked responses @couchdb", () => {
|
|||||||
// Override the first request to GET openmct/mine to return a 404.
|
// Override the first request to GET openmct/mine to return a 404.
|
||||||
// This simulates the case of starting Open MCT with a fresh database
|
// This simulates the case of starting Open MCT with a fresh database
|
||||||
// and no "My Items" folder created yet.
|
// and no "My Items" folder created yet.
|
||||||
await page.route('**/mine', route => {
|
await page.route(
|
||||||
|
'**/mine',
|
||||||
|
(route) => {
|
||||||
route.fulfill(mockedMissingObjectResponsefromCouchDB);
|
route.fulfill(mockedMissingObjectResponsefromCouchDB);
|
||||||
}, { times: 1 });
|
},
|
||||||
|
{ times: 1 }
|
||||||
|
);
|
||||||
|
|
||||||
// Set up promise to verify that a PUT request to create "My Items"
|
// Set up promise to verify that a PUT request to create "My Items"
|
||||||
// folder was made.
|
// folder was made.
|
||||||
const putMineFolderRequest = page.waitForRequest(req =>
|
const putMineFolderRequest = page.waitForRequest(
|
||||||
req.url().endsWith('/mine')
|
(req) => req.url().endsWith('/mine') && req.method() === 'PUT'
|
||||||
&& req.method() === 'PUT');
|
);
|
||||||
|
|
||||||
// Set up promise to verify that a GET request to retrieve "My Items"
|
// Set up promise to verify that a GET request to retrieve "My Items"
|
||||||
// folder was made.
|
// folder was made.
|
||||||
const getMineFolderRequest = page.waitForRequest(req =>
|
const getMineFolderRequest = page.waitForRequest(
|
||||||
req.url().endsWith('/mine')
|
(req) => req.url().endsWith('/mine') && req.method() === 'GET'
|
||||||
&& req.method() === 'GET');
|
);
|
||||||
|
|
||||||
// Go to baseURL.
|
// Go to baseURL.
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
// Wait for both requests to resolve.
|
// Wait for both requests to resolve.
|
||||||
await Promise.all([
|
await Promise.all([putMineFolderRequest, getMineFolderRequest]);
|
||||||
putMineFolderRequest,
|
|
||||||
getMineFolderRequest
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -47,7 +47,6 @@ test.describe('Example Event Generator CRUD Operations', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Example Event Generator Telemetry Event Verficiation', () => {
|
test.describe('Example Event Generator Telemetry Event Verficiation', () => {
|
||||||
|
|
||||||
test.fixme('telemetry is coming in for test event', async ({ page }) => {
|
test.fixme('telemetry is coming in for test event', async ({ page }) => {
|
||||||
// Go to object created in step one
|
// Go to object created in step one
|
||||||
// Verify the telemetry table is filled with > 1 row
|
// Verify the telemetry table is filled with > 1 row
|
||||||
|
@ -27,7 +27,10 @@ This test suite is dedicated to tests which verify the basic operations surround
|
|||||||
const { test, expect } = require('../../../../baseFixtures');
|
const { test, expect } = require('../../../../baseFixtures');
|
||||||
|
|
||||||
test.describe('Sine Wave Generator', () => {
|
test.describe('Sine Wave Generator', () => {
|
||||||
test('Create new Sine Wave Generator Object and validate create Form Logic', async ({ page, browserName }) => {
|
test('Create new Sine Wave Generator Object and validate create Form Logic', async ({
|
||||||
|
page,
|
||||||
|
browserName
|
||||||
|
}) => {
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(browserName === 'firefox', 'This test needs to be updated to work with firefox');
|
test.skip(browserName === 'firefox', 'This test needs to be updated to work with firefox');
|
||||||
|
|
||||||
@ -45,7 +48,9 @@ test.describe('Sine Wave Generator', () => {
|
|||||||
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/req/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/req/);
|
||||||
|
|
||||||
// Verify that the Notes row does not have a required indicator
|
// Verify that the Notes row does not have a required indicator
|
||||||
await expect(page.locator('.c-form__section div:nth-child(3) .form-row .c-form-row__state-indicator')).not.toContain('.req');
|
await expect(
|
||||||
|
page.locator('.c-form__section div:nth-child(3) .form-row .c-form-row__state-indicator')
|
||||||
|
).not.toContain('.req');
|
||||||
await page.locator('textarea[type="text"]').fill('Optional Note Text');
|
await page.locator('textarea[type="text"]').fill('Optional Note Text');
|
||||||
|
|
||||||
// Period
|
// Period
|
||||||
@ -67,20 +72,32 @@ test.describe('Sine Wave Generator', () => {
|
|||||||
await expect(page.locator('div:nth-child(9) .c-form-row__state-indicator')).toHaveClass(/req/);
|
await expect(page.locator('div:nth-child(9) .c-form-row__state-indicator')).toHaveClass(/req/);
|
||||||
|
|
||||||
// Verify that by removing value from required text field shows invalid indicator
|
// Verify that by removing value from required text field shows invalid indicator
|
||||||
await page.locator('text=Properties Title Notes Period Amplitude Offset Data Rate (hz) Phase (radians) Ra >> input[type="text"]').fill('');
|
await page
|
||||||
|
.locator(
|
||||||
|
'text=Properties Title Notes Period Amplitude Offset Data Rate (hz) Phase (radians) Ra >> input[type="text"]'
|
||||||
|
)
|
||||||
|
.fill('');
|
||||||
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/invalid/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/invalid/);
|
||||||
|
|
||||||
// Verify that by adding value to empty required text field changes invalid to valid indicator
|
// Verify that by adding value to empty required text field changes invalid to valid indicator
|
||||||
await page.locator('text=Properties Title Notes Period Amplitude Offset Data Rate (hz) Phase (radians) Ra >> input[type="text"]').fill('New Sine Wave Generator');
|
await page
|
||||||
|
.locator(
|
||||||
|
'text=Properties Title Notes Period Amplitude Offset Data Rate (hz) Phase (radians) Ra >> input[type="text"]'
|
||||||
|
)
|
||||||
|
.fill('New Sine Wave Generator');
|
||||||
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/valid/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).toHaveClass(/valid/);
|
||||||
|
|
||||||
// Verify that by removing value from required number field shows invalid indicator
|
// Verify that by removing value from required number field shows invalid indicator
|
||||||
await page.locator('.field.control.l-input-sm input').first().fill('');
|
await page.locator('.field.control.l-input-sm input').first().fill('');
|
||||||
await expect(page.locator('div:nth-child(4) .c-form-row__state-indicator')).toHaveClass(/invalid/);
|
await expect(page.locator('div:nth-child(4) .c-form-row__state-indicator')).toHaveClass(
|
||||||
|
/invalid/
|
||||||
|
);
|
||||||
|
|
||||||
// Verify that by adding value to empty required number field changes invalid to valid indicator
|
// Verify that by adding value to empty required number field changes invalid to valid indicator
|
||||||
await page.locator('.field.control.l-input-sm input').first().fill('3');
|
await page.locator('.field.control.l-input-sm input').first().fill('3');
|
||||||
await expect(page.locator('div:nth-child(4) .c-form-row__state-indicator')).toHaveClass(/valid/);
|
await expect(page.locator('div:nth-child(4) .c-form-row__state-indicator')).toHaveClass(
|
||||||
|
/valid/
|
||||||
|
);
|
||||||
|
|
||||||
// Verify that can change value of number field by up/down arrows keys
|
// Verify that can change value of number field by up/down arrows keys
|
||||||
// Click .field.control.l-input-sm input >> nth=0
|
// Click .field.control.l-input-sm input >> nth=0
|
||||||
@ -94,17 +111,19 @@ test.describe('Sine Wave Generator', () => {
|
|||||||
await expect(value).toBe('6');
|
await expect(value).toBe('6');
|
||||||
|
|
||||||
//Click text=OK
|
//Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([page.waitForNavigation(), page.click('button:has-text("OK")')]);
|
||||||
page.waitForNavigation(),
|
|
||||||
page.click('button:has-text("OK")')
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Verify that the Sine Wave Generator is displayed and correct
|
// Verify that the Sine Wave Generator is displayed and correct
|
||||||
// Verify object properties
|
// Verify object properties
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('New Sine Wave Generator');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(
|
||||||
|
'New Sine Wave Generator'
|
||||||
|
);
|
||||||
|
|
||||||
// Verify canvas rendered and can be interacted with
|
// Verify canvas rendered and can be interacted with
|
||||||
await page.locator('canvas').nth(1).click({
|
await page
|
||||||
|
.locator('canvas')
|
||||||
|
.nth(1)
|
||||||
|
.click({
|
||||||
position: {
|
position: {
|
||||||
x: 341,
|
x: 341,
|
||||||
y: 28
|
y: 28
|
||||||
@ -113,7 +132,8 @@ test.describe('Sine Wave Generator', () => {
|
|||||||
|
|
||||||
// Verify that where we click on canvas shows the number we clicked on
|
// Verify that where we click on canvas shows the number we clicked on
|
||||||
// Note that any number will do, we just care that a number exists
|
// Note that any number will do, we just care that a number exists
|
||||||
await expect(page.locator('.value-to-display-nearestValue')).toContainText(/[+-]?([0-9]*[.])?[0-9]+/);
|
await expect(page.locator('.value-to-display-nearestValue')).toContainText(
|
||||||
|
/[+-]?([0-9]*[.])?[0-9]+/
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,9 @@ const jsonFilePath = 'e2e/test-data/ExampleLayouts.json';
|
|||||||
const imageFilePath = 'e2e/test-data/rick.jpg';
|
const imageFilePath = 'e2e/test-data/rick.jpg';
|
||||||
|
|
||||||
test.describe('Form Validation Behavior', () => {
|
test.describe('Form Validation Behavior', () => {
|
||||||
test('Required Field indicators appear if title is empty and can be corrected', async ({ page }) => {
|
test('Required Field indicators appear if title is empty and can be corrected', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
@ -60,10 +62,7 @@ test.describe('Form Validation Behavior', () => {
|
|||||||
await expect(page.locator('.c-form-row__state-indicator').first()).not.toHaveClass(/invalid/);
|
await expect(page.locator('.c-form-row__state-indicator').first()).not.toHaveClass(/invalid/);
|
||||||
|
|
||||||
//Finish Creating Domain Object
|
//Finish Creating Domain Object
|
||||||
await Promise.all([
|
await Promise.all([page.waitForNavigation(), page.click('button:has-text("OK")')]);
|
||||||
page.waitForNavigation(),
|
|
||||||
page.click('button:has-text("OK")')
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Verify that the Domain Object has been created with the corrected title property
|
//Verify that the Domain Object has been created with the corrected title property
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText(TEST_FOLDER);
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(TEST_FOLDER);
|
||||||
@ -72,7 +71,9 @@ test.describe('Form Validation Behavior', () => {
|
|||||||
|
|
||||||
test.describe('Form File Input Behavior', () => {
|
test.describe('Form File Input Behavior', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../helper', 'addInitFileInputObject.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../helper', 'addInitFileInputObject.js')
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can select a JSON file type', async ({ page }) => {
|
test('Can select a JSON file type', async ({ page }) => {
|
||||||
@ -107,7 +108,9 @@ test.describe('Form File Input Behavior', () => {
|
|||||||
test.describe('Persistence operations @addInit', () => {
|
test.describe('Persistence operations @addInit', () => {
|
||||||
// add non persistable root item
|
// add non persistable root item
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../helper', 'addNoneditableObject.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../helper', 'addNoneditableObject.js')
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Persistability should be respected in the create form location field', async ({ page }) => {
|
test('Persistability should be respected in the create form location field', async ({ page }) => {
|
||||||
@ -130,7 +133,9 @@ test.describe('Persistence operations @addInit', () => {
|
|||||||
|
|
||||||
test.describe('Persistence operations @couchdb', () => {
|
test.describe('Persistence operations @couchdb', () => {
|
||||||
test.use({ failOnConsoleError: false });
|
test.use({ failOnConsoleError: false });
|
||||||
test('Editing object properties should generate a single persistence operation', async ({ page }) => {
|
test('Editing object properties should generate a single persistence operation', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5616'
|
description: 'https://github.com/nasa/openmct/issues/5616'
|
||||||
@ -145,7 +150,7 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
|
|
||||||
// Count all persistence operations (PUT requests) for this specific object
|
// Count all persistence operations (PUT requests) for this specific object
|
||||||
let putRequestCount = 0;
|
let putRequestCount = 0;
|
||||||
page.on('request', req => {
|
page.on('request', (req) => {
|
||||||
if (req.method() === 'PUT' && req.url().endsWith(clock.uuid)) {
|
if (req.method() === 'PUT' && req.url().endsWith(clock.uuid)) {
|
||||||
putRequestCount += 1;
|
putRequestCount += 1;
|
||||||
}
|
}
|
||||||
@ -156,15 +161,22 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
await page.click('li[title="Edit properties of this object."]');
|
await page.click('li[title="Edit properties of this object."]');
|
||||||
|
|
||||||
// Modify the display format from default 12hr -> 24hr and click 'Save'
|
// Modify the display format from default 12hr -> 24hr and click 'Save'
|
||||||
await page.locator('select[aria-label="12 or 24 hour clock"]').selectOption({ value: 'clock24' });
|
await page
|
||||||
|
.locator('select[aria-label="12 or 24 hour clock"]')
|
||||||
|
.selectOption({ value: 'clock24' });
|
||||||
await page.click('button[aria-label="Save"]');
|
await page.click('button[aria-label="Save"]');
|
||||||
|
|
||||||
await expect.poll(() => putRequestCount, {
|
await expect
|
||||||
|
.poll(() => putRequestCount, {
|
||||||
message: 'Verify a single PUT request was made to persist the object',
|
message: 'Verify a single PUT request was made to persist the object',
|
||||||
timeout: 1000
|
timeout: 1000
|
||||||
}).toEqual(1);
|
})
|
||||||
|
.toEqual(1);
|
||||||
});
|
});
|
||||||
test('Can create an object after a conflict error @couchdb @2p', async ({ page, openmctConfig }) => {
|
test('Can create an object after a conflict error @couchdb @2p', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5982'
|
description: 'https://github.com/nasa/openmct/issues/5982'
|
||||||
@ -201,9 +213,9 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
|
|
||||||
// Both pages: Fill in the 'Name' form field.
|
// Both pages: Fill in the 'Name' form field.
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
nameInput.fill(""),
|
nameInput.fill(''),
|
||||||
nameInput.fill(`Clock:${genUuid()}`),
|
nameInput.fill(`Clock:${genUuid()}`),
|
||||||
nameInput2.fill(""),
|
nameInput2.fill(''),
|
||||||
nameInput2.fill(`Clock:${genUuid()}`)
|
nameInput2.fill(`Clock:${genUuid()}`)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -212,10 +224,7 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
const testNotes = page.testNotes;
|
const testNotes = page.testNotes;
|
||||||
const notesInput = page.locator('form[name="mctForm"] #notes-textarea');
|
const notesInput = page.locator('form[name="mctForm"] #notes-textarea');
|
||||||
const notesInput2 = page2.locator('form[name="mctForm"] #notes-textarea');
|
const notesInput2 = page2.locator('form[name="mctForm"] #notes-textarea');
|
||||||
await Promise.all([
|
await Promise.all([notesInput.fill(testNotes), notesInput2.fill(testNotes)]);
|
||||||
notesInput.fill(testNotes),
|
|
||||||
notesInput2.fill(testNotes)
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Page 2: Click "OK" to create the domain object and wait for navigation.
|
// Page 2: Click "OK" to create the domain object and wait for navigation.
|
||||||
// This will update the composition of the parent folder, setting the
|
// This will update the composition of the parent folder, setting the
|
||||||
@ -241,9 +250,11 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// Page 1: Verify that the conflict has occurred and an error notification is displayed.
|
// Page 1: Verify that the conflict has occurred and an error notification is displayed.
|
||||||
await expect(page.locator('.c-message-banner__message', {
|
await expect(
|
||||||
hasText: "Conflict detected while saving mine"
|
page.locator('.c-message-banner__message', {
|
||||||
})).toBeVisible();
|
hasText: 'Conflict detected while saving mine'
|
||||||
|
})
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
// Page 1: Start logging console errors from this point on
|
// Page 1: Start logging console errors from this point on
|
||||||
let errors = [];
|
let errors = [];
|
||||||
@ -259,14 +270,19 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Page 1: Wait for save progress dialog to appear/disappear
|
// Page 1: Wait for save progress dialog to appear/disappear
|
||||||
await page.locator('.c-message-banner__message', {
|
await page
|
||||||
hasText: 'Do not navigate away from this page or close this browser tab while this message is displayed.',
|
.locator('.c-message-banner__message', {
|
||||||
|
hasText:
|
||||||
|
'Do not navigate away from this page or close this browser tab while this message is displayed.',
|
||||||
state: 'visible'
|
state: 'visible'
|
||||||
}).waitFor({ state: 'hidden' });
|
})
|
||||||
|
.waitFor({ state: 'hidden' });
|
||||||
|
|
||||||
// Page 1: Navigate to 'My Items' and verify that the second clock was created
|
// Page 1: Navigate to 'My Items' and verify that the second clock was created
|
||||||
await page.goto('./#/browse/mine');
|
await page.goto('./#/browse/mine');
|
||||||
await expect(page.locator(`.c-grid-item__name[title="${clockAfterConflict.name}"]`)).toBeVisible();
|
await expect(
|
||||||
|
page.locator(`.c-grid-item__name[title="${clockAfterConflict.name}"]`)
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
// Verify no console errors occurred
|
// Verify no console errors occurred
|
||||||
expect(errors).toHaveLength(0);
|
expect(errors).toHaveLength(0);
|
||||||
@ -274,9 +290,9 @@ test.describe('Persistence operations @couchdb', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Form Correctness by Object Type', () => {
|
test.describe('Form Correctness by Object Type', () => {
|
||||||
test.fixme('Verify correct behavior of number object (SWG)', async ({page}) => {});
|
test.fixme('Verify correct behavior of number object (SWG)', async ({ page }) => {});
|
||||||
test.fixme('Verify correct behavior of number object Timer', async ({page}) => {});
|
test.fixme('Verify correct behavior of number object Timer', async ({ page }) => {});
|
||||||
test.fixme('Verify correct behavior of number object Plan View', async ({page}) => {});
|
test.fixme('Verify correct behavior of number object Plan View', async ({ page }) => {});
|
||||||
test.fixme('Verify correct behavior of number object Clock', async ({page}) => {});
|
test.fixme('Verify correct behavior of number object Clock', async ({ page }) => {});
|
||||||
test.fixme('Verify correct behavior of number object Hyperlink', async ({page}) => {});
|
test.fixme('Verify correct behavior of number object Hyperlink', async ({ page }) => {});
|
||||||
});
|
});
|
||||||
|
@ -31,7 +31,9 @@ const path = require('path');
|
|||||||
test.describe('Persistence operations @addInit', () => {
|
test.describe('Persistence operations @addInit', () => {
|
||||||
// add non persistable root item
|
// add non persistable root item
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../helper', 'addNoneditableObject.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../helper', 'addNoneditableObject.js')
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Non-persistable objects should not show persistence related actions', async ({ page }) => {
|
test('Non-persistable objects should not show persistence related actions', async ({ page }) => {
|
||||||
@ -44,6 +46,14 @@ test.describe('Persistence operations @addInit', () => {
|
|||||||
const menuOptions = page.locator('.c-menu li');
|
const menuOptions = page.locator('.c-menu li');
|
||||||
|
|
||||||
await expect.soft(menuOptions).toContainText(['Open In New Tab', 'View', 'Create Link']);
|
await expect.soft(menuOptions).toContainText(['Open In New Tab', 'View', 'Create Link']);
|
||||||
await expect(menuOptions).not.toContainText(['Move', 'Duplicate', 'Remove', 'Add New Folder', 'Edit Properties...', 'Export as JSON', 'Import from JSON']);
|
await expect(menuOptions).not.toContainText([
|
||||||
|
'Move',
|
||||||
|
'Duplicate',
|
||||||
|
'Remove',
|
||||||
|
'Add New Folder',
|
||||||
|
'Edit Properties...',
|
||||||
|
'Export as JSON',
|
||||||
|
'Import from JSON'
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -28,7 +28,10 @@ const { test, expect } = require('../../pluginFixtures');
|
|||||||
const { createDomainObjectWithDefaults } = require('../../appActions');
|
const { createDomainObjectWithDefaults } = require('../../appActions');
|
||||||
|
|
||||||
test.describe('Move & link item tests', () => {
|
test.describe('Move & link item tests', () => {
|
||||||
test('Create a basic object and verify that it can be moved to another folder', async ({ page, openmctConfig }) => {
|
test('Create a basic object and verify that it can be moved to another folder', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
// Go to Open MCT
|
// Go to Open MCT
|
||||||
@ -55,18 +58,22 @@ test.describe('Move & link item tests', () => {
|
|||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
await treePane.getByRole('treeitem', {
|
await treePane
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: 'Parent Folder'
|
name: 'Parent Folder'
|
||||||
}).click({
|
})
|
||||||
|
.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.getByRole('menuitem', {
|
await page
|
||||||
|
.getByRole('menuitem', {
|
||||||
name: /Move/
|
name: /Move/
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
const createModalTree = page.getByRole('tree', {
|
const createModalTree = page.getByRole('tree', {
|
||||||
name: "Create Modal Tree"
|
name: 'Create Modal Tree'
|
||||||
});
|
});
|
||||||
const myItemsLocatorTreeItem = createModalTree.getByRole('treeitem', {
|
const myItemsLocatorTreeItem = createModalTree.getByRole('treeitem', {
|
||||||
name: myItemsFolderName
|
name: myItemsFolderName
|
||||||
@ -100,14 +107,18 @@ test.describe('Move & link item tests', () => {
|
|||||||
await page.locator('[aria-label="Cancel"]').click();
|
await page.locator('[aria-label="Cancel"]').click();
|
||||||
|
|
||||||
// Move Child Folder from Parent Folder to My Items
|
// Move Child Folder from Parent Folder to My Items
|
||||||
await treePane.getByRole('treeitem', {
|
await treePane
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: new RegExp(childFolder.name)
|
name: new RegExp(childFolder.name)
|
||||||
}).click({
|
})
|
||||||
|
.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
await page.getByRole('menuitem', {
|
await page
|
||||||
|
.getByRole('menuitem', {
|
||||||
name: /Move/
|
name: /Move/
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
await myItemsLocatorTreeItem.click();
|
await myItemsLocatorTreeItem.click();
|
||||||
|
|
||||||
await page.locator('[aria-label="Save"]').click();
|
await page.locator('[aria-label="Save"]').click();
|
||||||
@ -118,7 +129,10 @@ test.describe('Move & link item tests', () => {
|
|||||||
// Expect that Child Folder is in My Items, the root folder
|
// Expect that Child Folder is in My Items, the root folder
|
||||||
expect(myItemsPaneTreeItem.locator('nth=0:has(text=Child Folder)')).toBeTruthy();
|
expect(myItemsPaneTreeItem.locator('nth=0:has(text=Child Folder)')).toBeTruthy();
|
||||||
});
|
});
|
||||||
test('Create a basic object and verify that it cannot be moved to telemetry object without Composition Provider', async ({ page, openmctConfig }) => {
|
test('Create a basic object and verify that it cannot be moved to telemetry object without Composition Provider', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
// Go to Open MCT
|
// Go to Open MCT
|
||||||
@ -158,11 +172,10 @@ test.describe('Move & link item tests', () => {
|
|||||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||||
|
|
||||||
// Select Folder Object and select Move from context menu
|
// Select Folder Object and select Move from context menu
|
||||||
await Promise.all([
|
await Promise.all([page.waitForNavigation(), page.locator(`a:has-text("${folder}")`).click()]);
|
||||||
page.waitForNavigation(),
|
await page
|
||||||
page.locator(`a:has-text("${folder}")`).click()
|
.locator('.c-tree__item.is-navigated-object .c-tree__item__label .c-tree__item__type-icon')
|
||||||
]);
|
.click({
|
||||||
await page.locator('.c-tree__item.is-navigated-object .c-tree__item__label .c-tree__item__type-icon').click({
|
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
await page.locator('li.icon-move').click();
|
await page.locator('li.icon-move').click();
|
||||||
@ -175,7 +188,10 @@ test.describe('Move & link item tests', () => {
|
|||||||
expect(okButtonStateDisabled2).toBeTruthy();
|
expect(okButtonStateDisabled2).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Create a basic object and verify that it can be linked to another folder', async ({ page, openmctConfig }) => {
|
test('Create a basic object and verify that it can be linked to another folder', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
// Go to Open MCT
|
// Go to Open MCT
|
||||||
@ -202,18 +218,22 @@ test.describe('Move & link item tests', () => {
|
|||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
await treePane.getByRole('treeitem', {
|
await treePane
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: 'Parent Folder'
|
name: 'Parent Folder'
|
||||||
}).click({
|
})
|
||||||
|
.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.getByRole('menuitem', {
|
await page
|
||||||
|
.getByRole('menuitem', {
|
||||||
name: /Move/
|
name: /Move/
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
const createModalTree = page.getByRole('tree', {
|
const createModalTree = page.getByRole('tree', {
|
||||||
name: "Create Modal Tree"
|
name: 'Create Modal Tree'
|
||||||
});
|
});
|
||||||
const myItemsLocatorTreeItem = createModalTree.getByRole('treeitem', {
|
const myItemsLocatorTreeItem = createModalTree.getByRole('treeitem', {
|
||||||
name: myItemsFolderName
|
name: myItemsFolderName
|
||||||
@ -247,14 +267,18 @@ test.describe('Move & link item tests', () => {
|
|||||||
await page.locator('[aria-label="Cancel"]').click();
|
await page.locator('[aria-label="Cancel"]').click();
|
||||||
|
|
||||||
// Move Child Folder from Parent Folder to My Items
|
// Move Child Folder from Parent Folder to My Items
|
||||||
await treePane.getByRole('treeitem', {
|
await treePane
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: new RegExp(childFolder.name)
|
name: new RegExp(childFolder.name)
|
||||||
}).click({
|
})
|
||||||
|
.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
await page.getByRole('menuitem', {
|
await page
|
||||||
|
.getByRole('menuitem', {
|
||||||
name: /Link/
|
name: /Link/
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
await myItemsLocatorTreeItem.click();
|
await myItemsLocatorTreeItem.click();
|
||||||
|
|
||||||
await page.locator('[aria-label="Save"]').click();
|
await page.locator('[aria-label="Save"]').click();
|
||||||
@ -267,10 +291,13 @@ test.describe('Move & link item tests', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme('Cannot move a previously created domain object to non-peristable object in Move Modal', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Cannot move a previously created domain object to non-peristable object in Move Modal',
|
||||||
|
async ({ page }) => {
|
||||||
//Create a domain object
|
//Create a domain object
|
||||||
//Save Domain object
|
//Save Domain object
|
||||||
//Move Object and verify that cannot select non-persistable object
|
//Move Object and verify that cannot select non-persistable object
|
||||||
//Move Object to My Items
|
//Move Object to My Items
|
||||||
//Verify successful move
|
//Verify successful move
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
@ -59,10 +59,14 @@ test.describe('Notifications List', () => {
|
|||||||
await page.click('button[aria-label="Dismiss notification of Error message"]');
|
await page.click('button[aria-label="Dismiss notification of Error message"]');
|
||||||
|
|
||||||
// Verify there is no a notification (listitem) with the text "Error message" since it was dismissed
|
// Verify there is no a notification (listitem) with the text "Error message" since it was dismissed
|
||||||
expect(await page.locator('div[role="dialog"] div[role="listitem"]').innerText()).not.toContain('Error message');
|
expect(await page.locator('div[role="dialog"] div[role="listitem"]').innerText()).not.toContain(
|
||||||
|
'Error message'
|
||||||
|
);
|
||||||
|
|
||||||
// Verify there is still a notification (listitem) with the text "Alert message"
|
// Verify there is still a notification (listitem) with the text "Alert message"
|
||||||
expect(await page.locator('div[role="dialog"] div[role="listitem"]').innerText()).toContain('Alert message');
|
expect(await page.locator('div[role="dialog"] div[role="listitem"]').innerText()).toContain(
|
||||||
|
'Alert message'
|
||||||
|
);
|
||||||
|
|
||||||
// Click on button with aria-label="Dismiss notification of Alert message"
|
// Click on button with aria-label="Dismiss notification of Alert message"
|
||||||
await page.click('button[aria-label="Dismiss notification of Alert message"]');
|
await page.click('button[aria-label="Dismiss notification of Alert message"]');
|
||||||
@ -73,7 +77,9 @@ test.describe('Notifications List', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Notification Overlay', () => {
|
test.describe('Notification Overlay', () => {
|
||||||
test('Closing notification list after notification banner disappeared does not cause it to open automatically', async ({ page }) => {
|
test('Closing notification list after notification banner disappeared does not cause it to open automatically', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/6130'
|
description: 'https://github.com/nasa/openmct/issues/6130'
|
||||||
@ -92,7 +98,7 @@ test.describe('Notification Overlay', () => {
|
|||||||
expect(await page.locator('div[role="dialog"]').isVisible()).toBe(true);
|
expect(await page.locator('div[role="dialog"]').isVisible()).toBe(true);
|
||||||
|
|
||||||
// Wait until there is no Notification Banner
|
// Wait until there is no Notification Banner
|
||||||
await page.waitForSelector('div[role="alert"]', { state: 'detached'});
|
await page.waitForSelector('div[role="alert"]', { state: 'detached' });
|
||||||
|
|
||||||
// Click on the "Close" button of the Notification List
|
// Click on the "Close" button of the Notification List
|
||||||
await page.click('button[aria-label="Close"]');
|
await page.click('button[aria-label="Close"]');
|
||||||
|
@ -20,13 +20,20 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
const { test, expect } = require('../../../pluginFixtures');
|
const { test, expect } = require('../../../pluginFixtures');
|
||||||
const { createPlanFromJSON, createDomainObjectWithDefaults, selectInspectorTab } = require('../../../appActions');
|
const {
|
||||||
|
createPlanFromJSON,
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
selectInspectorTab
|
||||||
|
} = require('../../../appActions');
|
||||||
const testPlan1 = require('../../../test-data/examplePlans/ExamplePlan_Small1.json');
|
const testPlan1 = require('../../../test-data/examplePlans/ExamplePlan_Small1.json');
|
||||||
const testPlan2 = require('../../../test-data/examplePlans/ExamplePlan_Small2.json');
|
const testPlan2 = require('../../../test-data/examplePlans/ExamplePlan_Small2.json');
|
||||||
const { assertPlanActivities, setBoundsToSpanAllActivities } = require('../../../helper/planningUtils');
|
const {
|
||||||
|
assertPlanActivities,
|
||||||
|
setBoundsToSpanAllActivities
|
||||||
|
} = require('../../../helper/planningUtils');
|
||||||
const { getPreciseDuration } = require('../../../../src/utils/duration');
|
const { getPreciseDuration } = require('../../../../src/utils/duration');
|
||||||
|
|
||||||
test.describe("Gantt Chart", () => {
|
test.describe('Gantt Chart', () => {
|
||||||
let ganttChart;
|
let ganttChart;
|
||||||
let plan;
|
let plan;
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
@ -40,24 +47,28 @@ test.describe("Gantt Chart", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Displays all plan events", async ({ page }) => {
|
test('Displays all plan events', async ({ page }) => {
|
||||||
await page.goto(ganttChart.url);
|
await page.goto(ganttChart.url);
|
||||||
|
|
||||||
await assertPlanActivities(page, testPlan1, ganttChart.url);
|
await assertPlanActivities(page, testPlan1, ganttChart.url);
|
||||||
});
|
});
|
||||||
test("Replaces a plan with a new plan", async ({ page }) => {
|
test('Replaces a plan with a new plan', async ({ page }) => {
|
||||||
await assertPlanActivities(page, testPlan1, ganttChart.url);
|
await assertPlanActivities(page, testPlan1, ganttChart.url);
|
||||||
await createPlanFromJSON(page, {
|
await createPlanFromJSON(page, {
|
||||||
json: testPlan2,
|
json: testPlan2,
|
||||||
parent: ganttChart.uuid
|
parent: ganttChart.uuid
|
||||||
});
|
});
|
||||||
const replaceModal = page.getByRole('dialog').filter({ hasText: "This action will replace the current Plan. Do you want to continue?" });
|
const replaceModal = page
|
||||||
|
.getByRole('dialog')
|
||||||
|
.filter({ hasText: 'This action will replace the current Plan. Do you want to continue?' });
|
||||||
await expect(replaceModal).toBeVisible();
|
await expect(replaceModal).toBeVisible();
|
||||||
await page.getByRole('button', { name: 'OK' }).click();
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
|
||||||
await assertPlanActivities(page, testPlan2, ganttChart.url);
|
await assertPlanActivities(page, testPlan2, ganttChart.url);
|
||||||
});
|
});
|
||||||
test("Can select a single activity and display its details in the inspector", async ({ page }) => {
|
test('Can select a single activity and display its details in the inspector', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.slow();
|
test.slow();
|
||||||
await page.goto(ganttChart.url);
|
await page.goto(ganttChart.url);
|
||||||
|
|
||||||
@ -65,12 +76,23 @@ test.describe("Gantt Chart", () => {
|
|||||||
|
|
||||||
const activities = Object.values(testPlan1).flat();
|
const activities = Object.values(testPlan1).flat();
|
||||||
const activity = activities[0];
|
const activity = activities[0];
|
||||||
await page.locator('g').filter({ hasText: new RegExp(activity.name) }).click();
|
await page
|
||||||
|
.locator('g')
|
||||||
|
.filter({ hasText: new RegExp(activity.name) })
|
||||||
|
.click();
|
||||||
await selectInspectorTab(page, 'Activity');
|
await selectInspectorTab(page, 'Activity');
|
||||||
|
|
||||||
const startDateTime = await page.locator('.c-inspect-properties__label:has-text("Start DateTime")+.c-inspect-properties__value').innerText();
|
const startDateTime = await page
|
||||||
const endDateTime = await page.locator('.c-inspect-properties__label:has-text("End DateTime")+.c-inspect-properties__value').innerText();
|
.locator(
|
||||||
const duration = await page.locator('.c-inspect-properties__label:has-text("duration")+.c-inspect-properties__value').innerText();
|
'.c-inspect-properties__label:has-text("Start DateTime")+.c-inspect-properties__value'
|
||||||
|
)
|
||||||
|
.innerText();
|
||||||
|
const endDateTime = await page
|
||||||
|
.locator('.c-inspect-properties__label:has-text("End DateTime")+.c-inspect-properties__value')
|
||||||
|
.innerText();
|
||||||
|
const duration = await page
|
||||||
|
.locator('.c-inspect-properties__label:has-text("duration")+.c-inspect-properties__value')
|
||||||
|
.innerText();
|
||||||
|
|
||||||
const expectedStartDate = new Date(activity.start).toISOString();
|
const expectedStartDate = new Date(activity.start).toISOString();
|
||||||
const actualStartDate = new Date(startDateTime).toISOString();
|
const actualStartDate = new Date(startDateTime).toISOString();
|
||||||
@ -98,6 +120,8 @@ test.describe("Gantt Chart", () => {
|
|||||||
await page.goto(ganttChart.url);
|
await page.goto(ganttChart.url);
|
||||||
|
|
||||||
// Assert that the Plan's status is displayed as draft
|
// Assert that the Plan's status is displayed as draft
|
||||||
expect(await page.locator('.u-contents.c-swimlane.is-status--draft').count()).toBe(Object.keys(testPlan1).length);
|
expect(await page.locator('.u-contents.c-swimlane.is-status--draft').count()).toBe(
|
||||||
|
Object.keys(testPlan1).length
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ const { createPlanFromJSON } = require('../../../appActions');
|
|||||||
const testPlan1 = require('../../../test-data/examplePlans/ExamplePlan_Small1.json');
|
const testPlan1 = require('../../../test-data/examplePlans/ExamplePlan_Small1.json');
|
||||||
const { assertPlanActivities } = require('../../../helper/planningUtils');
|
const { assertPlanActivities } = require('../../../helper/planningUtils');
|
||||||
|
|
||||||
test.describe("Plan", () => {
|
test.describe('Plan', () => {
|
||||||
let plan;
|
let plan;
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
@ -33,7 +33,7 @@ test.describe("Plan", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Displays all plan events", async ({ page }) => {
|
test('Displays all plan events', async ({ page }) => {
|
||||||
await assertPlanActivities(page, testPlan1, plan.url);
|
await assertPlanActivities(page, testPlan1, plan.url);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -24,65 +24,69 @@ const { test, expect } = require('../../../pluginFixtures');
|
|||||||
const { createDomainObjectWithDefaults, createPlanFromJSON } = require('../../../appActions');
|
const { createDomainObjectWithDefaults, createPlanFromJSON } = require('../../../appActions');
|
||||||
|
|
||||||
const testPlan = {
|
const testPlan = {
|
||||||
"TEST_GROUP": [
|
TEST_GROUP: [
|
||||||
{
|
{
|
||||||
"name": "Past event 1",
|
name: 'Past event 1',
|
||||||
"start": 1660320408000,
|
start: 1660320408000,
|
||||||
"end": 1660343797000,
|
end: 1660343797000,
|
||||||
"type": "TEST-GROUP",
|
type: 'TEST-GROUP',
|
||||||
"color": "orange",
|
color: 'orange',
|
||||||
"textColor": "white"
|
textColor: 'white'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Past event 2",
|
name: 'Past event 2',
|
||||||
"start": 1660406808000,
|
start: 1660406808000,
|
||||||
"end": 1660429160000,
|
end: 1660429160000,
|
||||||
"type": "TEST-GROUP",
|
type: 'TEST-GROUP',
|
||||||
"color": "orange",
|
color: 'orange',
|
||||||
"textColor": "white"
|
textColor: 'white'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Past event 3",
|
name: 'Past event 3',
|
||||||
"start": 1660493208000,
|
start: 1660493208000,
|
||||||
"end": 1660503981000,
|
end: 1660503981000,
|
||||||
"type": "TEST-GROUP",
|
type: 'TEST-GROUP',
|
||||||
"color": "orange",
|
color: 'orange',
|
||||||
"textColor": "white"
|
textColor: 'white'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Past event 4",
|
name: 'Past event 4',
|
||||||
"start": 1660579608000,
|
start: 1660579608000,
|
||||||
"end": 1660624108000,
|
end: 1660624108000,
|
||||||
"type": "TEST-GROUP",
|
type: 'TEST-GROUP',
|
||||||
"color": "orange",
|
color: 'orange',
|
||||||
"textColor": "white"
|
textColor: 'white'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Past event 5",
|
name: 'Past event 5',
|
||||||
"start": 1660666008000,
|
start: 1660666008000,
|
||||||
"end": 1660681529000,
|
end: 1660681529000,
|
||||||
"type": "TEST-GROUP",
|
type: 'TEST-GROUP',
|
||||||
"color": "orange",
|
color: 'orange',
|
||||||
"textColor": "white"
|
textColor: 'white'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
test.describe("Time Strip", () => {
|
test.describe('Time Strip', () => {
|
||||||
test("Create two Time Strips, add a single Plan to both, and verify they can have separate Indepdenent Time Contexts @unstable", async ({ page }) => {
|
test('Create two Time Strips, add a single Plan to both, and verify they can have separate Indepdenent Time Contexts @unstable', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5627'
|
description: 'https://github.com/nasa/openmct/issues/5627'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Constant locators
|
// Constant locators
|
||||||
const independentTimeConductorInputs = page.locator('.l-shell__main-independent-time-conductor .c-input--datetime');
|
const independentTimeConductorInputs = page.locator(
|
||||||
|
'.l-shell__main-independent-time-conductor .c-input--datetime'
|
||||||
|
);
|
||||||
const activityBounds = page.locator('.activity-bounds');
|
const activityBounds = page.locator('.activity-bounds');
|
||||||
|
|
||||||
// Goto baseURL
|
// Goto baseURL
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
const timestrip = await test.step("Create a Time Strip", async () => {
|
const timestrip = await test.step('Create a Time Strip', async () => {
|
||||||
const createdTimeStrip = await createDomainObjectWithDefaults(page, { type: 'Time Strip' });
|
const createdTimeStrip = await createDomainObjectWithDefaults(page, { type: 'Time Strip' });
|
||||||
const objectName = await page.locator('.l-browse-bar__object-name').innerText();
|
const objectName = await page.locator('.l-browse-bar__object-name').innerText();
|
||||||
expect(objectName).toBe(createdTimeStrip.name);
|
expect(objectName).toBe(createdTimeStrip.name);
|
||||||
@ -90,7 +94,7 @@ test.describe("Time Strip", () => {
|
|||||||
return createdTimeStrip;
|
return createdTimeStrip;
|
||||||
});
|
});
|
||||||
|
|
||||||
const plan = await test.step("Create a Plan and add it to the timestrip", async () => {
|
const plan = await test.step('Create a Plan and add it to the timestrip', async () => {
|
||||||
const createdPlan = await createPlanFromJSON(page, {
|
const createdPlan = await createPlanFromJSON(page, {
|
||||||
name: 'Test Plan',
|
name: 'Test Plan',
|
||||||
json: testPlan
|
json: testPlan
|
||||||
@ -106,7 +110,9 @@ test.describe("Time Strip", () => {
|
|||||||
const endBound = testPlan.TEST_GROUP[testPlan.TEST_GROUP.length - 1].end;
|
const endBound = testPlan.TEST_GROUP[testPlan.TEST_GROUP.length - 1].end;
|
||||||
|
|
||||||
// Switch to fixed time mode with all plan events within the bounds
|
// Switch to fixed time mode with all plan events within the bounds
|
||||||
await page.goto(`${timestrip.url}?tc.mode=fixed&tc.startBound=${startBound}&tc.endBound=${endBound}&tc.timeSystem=utc&view=time-strip.view`);
|
await page.goto(
|
||||||
|
`${timestrip.url}?tc.mode=fixed&tc.startBound=${startBound}&tc.endBound=${endBound}&tc.timeSystem=utc&view=time-strip.view`
|
||||||
|
);
|
||||||
|
|
||||||
// Verify all events are displayed
|
// Verify all events are displayed
|
||||||
const eventCount = await page.locator('.activity-bounds').count();
|
const eventCount = await page.locator('.activity-bounds').count();
|
||||||
@ -115,7 +121,7 @@ test.describe("Time Strip", () => {
|
|||||||
return createdPlan;
|
return createdPlan;
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("TimeStrip can use the Independent Time Conductor", async () => {
|
await test.step('TimeStrip can use the Independent Time Conductor', async () => {
|
||||||
// Activate Independent Time Conductor in Fixed Time Mode
|
// Activate Independent Time Conductor in Fixed Time Mode
|
||||||
await page.click('.c-toggle-switch__slider');
|
await page.click('.c-toggle-switch__slider');
|
||||||
expect(await activityBounds.count()).toEqual(0);
|
expect(await activityBounds.count()).toEqual(0);
|
||||||
@ -135,11 +141,11 @@ test.describe("Time Strip", () => {
|
|||||||
expect(await activityBounds.count()).toEqual(1);
|
expect(await activityBounds.count()).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("Can have multiple TimeStrips with the same plan linked and different Independent Time Contexts", async () => {
|
await test.step('Can have multiple TimeStrips with the same plan linked and different Independent Time Contexts', async () => {
|
||||||
// Create another Time Strip and verify that it has been created
|
// Create another Time Strip and verify that it has been created
|
||||||
const createdTimeStrip = await createDomainObjectWithDefaults(page, {
|
const createdTimeStrip = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Time Strip',
|
type: 'Time Strip',
|
||||||
name: "Another Time Strip"
|
name: 'Another Time Strip'
|
||||||
});
|
});
|
||||||
|
|
||||||
const objectName = await page.locator('.l-browse-bar__object-name').innerText();
|
const objectName = await page.locator('.l-browse-bar__object-name').innerText();
|
||||||
|
@ -27,8 +27,9 @@ This test suite is dedicated to tests which verify the basic operations surround
|
|||||||
const { test, expect } = require('../../../../baseFixtures');
|
const { test, expect } = require('../../../../baseFixtures');
|
||||||
|
|
||||||
test.describe('Clock Generator CRUD Operations', () => {
|
test.describe('Clock Generator CRUD Operations', () => {
|
||||||
|
test('Timezone dropdown will collapse when clicked outside or on dropdown icon again', async ({
|
||||||
test('Timezone dropdown will collapse when clicked outside or on dropdown icon again', async ({ page }) => {
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/4878'
|
description: 'https://github.com/nasa/openmct/issues/4878'
|
||||||
@ -45,22 +46,21 @@ test.describe('Clock Generator CRUD Operations', () => {
|
|||||||
// Click .icon-arrow-down
|
// Click .icon-arrow-down
|
||||||
await page.locator('.icon-arrow-down').click();
|
await page.locator('.icon-arrow-down').click();
|
||||||
//verify if the autocomplete dropdown is visible
|
//verify if the autocomplete dropdown is visible
|
||||||
await expect(page.locator(".c-input--autocomplete__options")).toBeVisible();
|
await expect(page.locator('.c-input--autocomplete__options')).toBeVisible();
|
||||||
// Click .icon-arrow-down
|
// Click .icon-arrow-down
|
||||||
await page.locator('.icon-arrow-down').click();
|
await page.locator('.icon-arrow-down').click();
|
||||||
|
|
||||||
// Verify clicking on the autocomplete arrow collapses the dropdown
|
// Verify clicking on the autocomplete arrow collapses the dropdown
|
||||||
await expect(page.locator(".c-input--autocomplete__options")).toBeHidden();
|
await expect(page.locator('.c-input--autocomplete__options')).toBeHidden();
|
||||||
|
|
||||||
// Click timezone input to open dropdown
|
// Click timezone input to open dropdown
|
||||||
await page.locator('.c-input--autocomplete__input').click();
|
await page.locator('.c-input--autocomplete__input').click();
|
||||||
//verify if the autocomplete dropdown is visible
|
//verify if the autocomplete dropdown is visible
|
||||||
await expect(page.locator(".c-input--autocomplete__options")).toBeVisible();
|
await expect(page.locator('.c-input--autocomplete__options')).toBeVisible();
|
||||||
|
|
||||||
// Verify clicking outside the autocomplete dropdown collapses it
|
// Verify clicking outside the autocomplete dropdown collapses it
|
||||||
await page.locator('text=Timezone').click();
|
await page.locator('text=Timezone').click();
|
||||||
// Verify clicking on the autocomplete arrow collapses the dropdown
|
// Verify clicking on the autocomplete arrow collapses the dropdown
|
||||||
await expect(page.locator(".c-input--autocomplete__options")).toBeHidden();
|
await expect(page.locator('.c-input--autocomplete__options')).toBeHidden();
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -33,7 +33,7 @@ let conditionSetUrl;
|
|||||||
let getConditionSetIdentifierFromUrl;
|
let getConditionSetIdentifierFromUrl;
|
||||||
|
|
||||||
test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
||||||
test.beforeAll(async ({ browser}) => {
|
test.beforeAll(async ({ browser }) => {
|
||||||
//TODO: This needs to be refactored
|
//TODO: This needs to be refactored
|
||||||
const context = await browser.newContext();
|
const context = await browser.newContext();
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
@ -42,10 +42,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
|
|
||||||
await page.locator('li[role="menuitem"]:has-text("Condition Set")').click();
|
await page.locator('li[role="menuitem"]:has-text("Condition Set")').click();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([page.waitForNavigation(), page.click('button:has-text("OK")')]);
|
||||||
page.waitForNavigation(),
|
|
||||||
page.click('button:has-text("OK")')
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Save localStorage for future test execution
|
//Save localStorage for future test execution
|
||||||
await context.storageState({ path: './e2e/test-data/recycled_local_storage.json' });
|
await context.storageState({ path: './e2e/test-data/recycled_local_storage.json' });
|
||||||
@ -62,27 +59,29 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
test.use({ storageState: './e2e/test-data/recycled_local_storage.json' });
|
test.use({ storageState: './e2e/test-data/recycled_local_storage.json' });
|
||||||
|
|
||||||
//Begin suite of tests again localStorage
|
//Begin suite of tests again localStorage
|
||||||
test('Condition set object properties persist in main view and inspector @localStorage', async ({ page }) => {
|
test('Condition set object properties persist in main view and inspector @localStorage', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
//Navigate to baseURL with injected localStorage
|
//Navigate to baseURL with injected localStorage
|
||||||
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Unnamed Condition Set');
|
||||||
|
|
||||||
//Assertions on loaded Condition Set in Inspector
|
//Assertions on loaded Condition Set in Inspector
|
||||||
expect.soft(page.locator('_vue=item.name=Unnamed Condition Set')).toBeTruthy();
|
expect.soft(page.locator('_vue=item.name=Unnamed Condition Set')).toBeTruthy();
|
||||||
|
|
||||||
//Reload Page
|
//Reload Page
|
||||||
await Promise.all([
|
await Promise.all([page.reload(), page.waitForLoadState('networkidle')]);
|
||||||
page.reload(),
|
|
||||||
page.waitForLoadState('networkidle')
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Re-verify after reload
|
//Re-verify after reload
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Unnamed Condition Set');
|
||||||
//Assertions on loaded Condition Set in Inspector
|
//Assertions on loaded Condition Set in Inspector
|
||||||
expect.soft(page.locator('_vue=item.name=Unnamed Condition Set')).toBeTruthy();
|
expect.soft(page.locator('_vue=item.name=Unnamed Condition Set')).toBeTruthy();
|
||||||
|
|
||||||
});
|
});
|
||||||
test('condition set object can be modified on @localStorage', async ({ page, openmctConfig }) => {
|
test('condition set object can be modified on @localStorage', async ({ page, openmctConfig }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
@ -90,22 +89,37 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Unnamed Condition Set');
|
||||||
|
|
||||||
//Update the Condition Set properties
|
//Update the Condition Set properties
|
||||||
// Click Edit Button
|
// Click Edit Button
|
||||||
await page.locator('text=Conditions View Snapshot >> button').nth(3).click();
|
await page.locator('text=Conditions View Snapshot >> button').nth(3).click();
|
||||||
|
|
||||||
//Edit Condition Set Name from main view
|
//Edit Condition Set Name from main view
|
||||||
await page.locator('.l-browse-bar__object-name').filter({ hasText: 'Unnamed Condition Set' }).first().fill('Renamed Condition Set');
|
await page
|
||||||
await page.locator('.l-browse-bar__object-name').filter({ hasText: 'Renamed Condition Set' }).first().press('Enter');
|
.locator('.l-browse-bar__object-name')
|
||||||
|
.filter({ hasText: 'Unnamed Condition Set' })
|
||||||
|
.first()
|
||||||
|
.fill('Renamed Condition Set');
|
||||||
|
await page
|
||||||
|
.locator('.l-browse-bar__object-name')
|
||||||
|
.filter({ hasText: 'Renamed Condition Set' })
|
||||||
|
.first()
|
||||||
|
.press('Enter');
|
||||||
// Click Save Button
|
// Click Save Button
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
// Click Save and Finish Editing Option
|
// Click Save and Finish Editing Option
|
||||||
await page.locator('text=Save and Finish Editing').click();
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
|
|
||||||
//Verify Main section reflects updated Name Property
|
//Verify Main section reflects updated Name Property
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Renamed Condition Set');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Renamed Condition Set');
|
||||||
|
|
||||||
// Verify Inspector properties
|
// Verify Inspector properties
|
||||||
// Verify Inspector has updated Name property
|
// Verify Inspector has updated Name property
|
||||||
@ -123,13 +137,12 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
expect(page.locator('a:has-text("Renamed Condition Set")')).toBeTruthy();
|
expect(page.locator('a:has-text("Renamed Condition Set")')).toBeTruthy();
|
||||||
|
|
||||||
//Reload Page
|
//Reload Page
|
||||||
await Promise.all([
|
await Promise.all([page.reload(), page.waitForLoadState('networkidle')]);
|
||||||
page.reload(),
|
|
||||||
page.waitForLoadState('networkidle')
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Verify Main section reflects updated Name Property
|
//Verify Main section reflects updated Name Property
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Renamed Condition Set');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Renamed Condition Set');
|
||||||
|
|
||||||
// Verify Inspector properties
|
// Verify Inspector properties
|
||||||
// Verify Inspector has updated Name property
|
// Verify Inspector has updated Name property
|
||||||
@ -146,19 +159,30 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Renamed');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Renamed');
|
||||||
expect(page.locator('a:has-text("Renamed Condition Set")')).toBeTruthy();
|
expect(page.locator('a:has-text("Renamed Condition Set")')).toBeTruthy();
|
||||||
});
|
});
|
||||||
test('condition set object can be deleted by Search Tree Actions menu on @localStorage', async ({ page }) => {
|
test('condition set object can be deleted by Search Tree Actions menu on @localStorage', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
//Navigate to baseURL
|
//Navigate to baseURL
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
//Assertions on loaded Condition Set in main view. This is a stateful transition step after page.goto()
|
||||||
await expect(page.locator('a:has-text("Unnamed Condition Set Condition Set") >> nth=0')).toBeVisible();
|
await expect(
|
||||||
|
page.locator('a:has-text("Unnamed Condition Set Condition Set") >> nth=0')
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
const numberOfConditionSetsToStart = await page.locator('a:has-text("Unnamed Condition Set Condition Set")').count();
|
const numberOfConditionSetsToStart = await page
|
||||||
|
.locator('a:has-text("Unnamed Condition Set Condition Set")')
|
||||||
|
.count();
|
||||||
|
|
||||||
// Search for Unnamed Condition Set
|
// Search for Unnamed Condition Set
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Unnamed Condition Set');
|
await page
|
||||||
|
.locator('[aria-label="OpenMCT Search"] input[type="search"]')
|
||||||
|
.fill('Unnamed Condition Set');
|
||||||
// Click Search Result
|
// Click Search Result
|
||||||
await page.locator('[aria-label="OpenMCT Search"] >> text=Unnamed Condition Set').first().click();
|
await page
|
||||||
|
.locator('[aria-label="OpenMCT Search"] >> text=Unnamed Condition Set')
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
// Click hamburger button
|
// Click hamburger button
|
||||||
await page.locator('[title="More options"]').click();
|
await page.locator('[title="More options"]').click();
|
||||||
|
|
||||||
@ -167,7 +191,9 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
await page.locator('button:has-text("OK")').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
|
|
||||||
//Expect Unnamed Condition Set to be removed in Main View
|
//Expect Unnamed Condition Set to be removed in Main View
|
||||||
const numberOfConditionSetsAtEnd = await page.locator('a:has-text("Unnamed Condition Set Condition Set")').count();
|
const numberOfConditionSetsAtEnd = await page
|
||||||
|
.locator('a:has-text("Unnamed Condition Set Condition Set")')
|
||||||
|
.count();
|
||||||
|
|
||||||
expect(numberOfConditionSetsAtEnd).toEqual(numberOfConditionSetsToStart - 1);
|
expect(numberOfConditionSetsAtEnd).toEqual(numberOfConditionSetsToStart - 1);
|
||||||
|
|
||||||
@ -175,7 +201,6 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
|
|||||||
//Domain Object is still available by direct URL after delete
|
//Domain Object is still available by direct URL after delete
|
||||||
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
await page.goto(conditionSetUrl, { waitUntil: 'networkidle' });
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set');
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -188,7 +213,7 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
// Create a new condition set
|
// Create a new condition set
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Condition Set',
|
type: 'Condition Set',
|
||||||
name: "Test Condition Set"
|
name: 'Test Condition Set'
|
||||||
});
|
});
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -207,15 +232,15 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
name: "Alpha Sine Wave Generator"
|
name: 'Alpha Sine Wave Generator'
|
||||||
});
|
});
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
name: "Beta Sine Wave Generator"
|
name: 'Beta Sine Wave Generator'
|
||||||
});
|
});
|
||||||
const conditionSet1 = await createDomainObjectWithDefaults(page, {
|
const conditionSet1 = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Condition Set',
|
type: 'Condition Set',
|
||||||
name: "Test Condition Set"
|
name: 'Test Condition Set'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
@ -228,8 +253,12 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
const alphaGeneratorTreeItem = treePane.getByRole('treeitem', { name: "Alpha Sine Wave Generator"});
|
const alphaGeneratorTreeItem = treePane.getByRole('treeitem', {
|
||||||
const betaGeneratorTreeItem = treePane.getByRole('treeitem', { name: "Beta Sine Wave Generator"});
|
name: 'Alpha Sine Wave Generator'
|
||||||
|
});
|
||||||
|
const betaGeneratorTreeItem = treePane.getByRole('treeitem', {
|
||||||
|
name: 'Beta Sine Wave Generator'
|
||||||
|
});
|
||||||
const conditionCollection = page.locator('#conditionCollection');
|
const conditionCollection = page.locator('#conditionCollection');
|
||||||
|
|
||||||
await alphaGeneratorTreeItem.dragTo(conditionCollection);
|
await alphaGeneratorTreeItem.dragTo(conditionCollection);
|
||||||
@ -256,7 +285,7 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
await page.click(`li[role='menuitem']:text("Sine Wave Generator")`);
|
await page.click(`li[role='menuitem']:text("Sine Wave Generator")`);
|
||||||
await page.getByRole('spinbutton', { name: 'Loading Delay (ms)' }).fill('8000');
|
await page.getByRole('spinbutton', { name: 'Loading Delay (ms)' }).fill('8000');
|
||||||
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
||||||
await nameInput.fill("Delayed Sine Wave Generator");
|
await nameInput.fill('Delayed Sine Wave Generator');
|
||||||
|
|
||||||
// Click OK button and wait for Navigate event
|
// Click OK button and wait for Navigate event
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -269,7 +298,7 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
// Create a new condition set
|
// Create a new condition set
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Condition Set',
|
type: 'Condition Set',
|
||||||
name: "Test Blank Output of Condition Set"
|
name: 'Test Blank Output of Condition Set'
|
||||||
});
|
});
|
||||||
// Change the object to edit mode
|
// Change the object to edit mode
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -286,34 +315,48 @@ test.describe('Basic Condition Set Use', () => {
|
|||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', { name: "Delayed Sine Wave Generator"});
|
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
|
||||||
|
name: 'Delayed Sine Wave Generator'
|
||||||
|
});
|
||||||
const conditionCollection = await page.locator('#conditionCollection');
|
const conditionCollection = await page.locator('#conditionCollection');
|
||||||
|
|
||||||
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
|
await sineWaveGeneratorTreeItem.dragTo(conditionCollection);
|
||||||
|
|
||||||
const firstCriterionTelemetry = await page.locator('[aria-label="Criterion Telemetry Selection"] >> nth=0');
|
const firstCriterionTelemetry = await page.locator(
|
||||||
|
'[aria-label="Criterion Telemetry Selection"] >> nth=0'
|
||||||
|
);
|
||||||
firstCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
firstCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
||||||
|
|
||||||
const secondCriterionTelemetry = await page.locator('[aria-label="Criterion Telemetry Selection"] >> nth=1');
|
const secondCriterionTelemetry = await page.locator(
|
||||||
|
'[aria-label="Criterion Telemetry Selection"] >> nth=1'
|
||||||
|
);
|
||||||
secondCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
secondCriterionTelemetry.selectOption({ label: 'Delayed Sine Wave Generator' });
|
||||||
|
|
||||||
const firstCriterionMetadata = await page.locator('[aria-label="Criterion Metadata Selection"] >> nth=0');
|
const firstCriterionMetadata = await page.locator(
|
||||||
|
'[aria-label="Criterion Metadata Selection"] >> nth=0'
|
||||||
|
);
|
||||||
firstCriterionMetadata.selectOption({ label: 'Sine' });
|
firstCriterionMetadata.selectOption({ label: 'Sine' });
|
||||||
|
|
||||||
const secondCriterionMetadata = await page.locator('[aria-label="Criterion Metadata Selection"] >> nth=1');
|
const secondCriterionMetadata = await page.locator(
|
||||||
|
'[aria-label="Criterion Metadata Selection"] >> nth=1'
|
||||||
|
);
|
||||||
secondCriterionMetadata.selectOption({ label: 'Sine' });
|
secondCriterionMetadata.selectOption({ label: 'Sine' });
|
||||||
|
|
||||||
const firstCriterionComparison = await page.locator('[aria-label="Criterion Comparison Selection"] >> nth=0');
|
const firstCriterionComparison = await page.locator(
|
||||||
|
'[aria-label="Criterion Comparison Selection"] >> nth=0'
|
||||||
|
);
|
||||||
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
|
firstCriterionComparison.selectOption({ label: 'is greater than or equal to' });
|
||||||
|
|
||||||
const secondCriterionComparison = await page.locator('[aria-label="Criterion Comparison Selection"] >> nth=1');
|
const secondCriterionComparison = await page.locator(
|
||||||
|
'[aria-label="Criterion Comparison Selection"] >> nth=1'
|
||||||
|
);
|
||||||
secondCriterionComparison.selectOption({ label: 'is less than' });
|
secondCriterionComparison.selectOption({ label: 'is less than' });
|
||||||
|
|
||||||
const firstCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=0');
|
const firstCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=0');
|
||||||
await firstCriterionInput.fill("0");
|
await firstCriterionInput.fill('0');
|
||||||
|
|
||||||
const secondCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=1');
|
const secondCriterionInput = await page.locator('[aria-label="Criterion Input"] >> nth=1');
|
||||||
await secondCriterionInput.fill("0");
|
await secondCriterionInput.fill('0');
|
||||||
|
|
||||||
const saveButtonLocator = page.locator('button[title="Save"]');
|
const saveButtonLocator = page.locator('button[title="Save"]');
|
||||||
await saveButtonLocator.click();
|
await saveButtonLocator.click();
|
||||||
|
@ -21,7 +21,12 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode } = require('../../../../appActions');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
setStartOffset,
|
||||||
|
setFixedTimeMode,
|
||||||
|
setRealTimeMode
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Display Layout', () => {
|
test.describe('Display Layout', () => {
|
||||||
/** @type {import('../../../../appActions').CreatedObjectInfo} */
|
/** @type {import('../../../../appActions').CreatedObjectInfo} */
|
||||||
@ -35,11 +40,13 @@ test.describe('Display Layout', () => {
|
|||||||
type: 'Sine Wave Generator'
|
type: 'Sine Wave Generator'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in real time', async ({ page }) => {
|
test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in real time', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create a Display Layout
|
// Create a Display Layout
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Display Layout',
|
type: 'Display Layout',
|
||||||
name: "Test Display Layout"
|
name: 'Test Display Layout'
|
||||||
});
|
});
|
||||||
// Edit Display Layout
|
// Edit Display Layout
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -63,17 +70,21 @@ test.describe('Display Layout', () => {
|
|||||||
// from the Sine Wave Generator
|
// from the Sine Wave Generator
|
||||||
const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
|
const getTelemValuePromise = await subscribeToTelemetry(page, sineWaveObject.uuid);
|
||||||
const formattedTelemetryValue = getTelemValuePromise;
|
const formattedTelemetryValue = getTelemValuePromise;
|
||||||
const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
|
const displayLayoutValuePromise = await page.waitForSelector(
|
||||||
|
`text="${formattedTelemetryValue}"`
|
||||||
|
);
|
||||||
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
||||||
const trimmedDisplayValue = displayLayoutValue.trim();
|
const trimmedDisplayValue = displayLayoutValue.trim();
|
||||||
|
|
||||||
expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
||||||
});
|
});
|
||||||
test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in fixed time', async ({ page }) => {
|
test('alpha-numeric widget telemetry value exactly matches latest telemetry value received in fixed time', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create a Display Layout
|
// Create a Display Layout
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Display Layout',
|
type: 'Display Layout',
|
||||||
name: "Test Display Layout"
|
name: 'Test Display Layout'
|
||||||
});
|
});
|
||||||
// Edit Display Layout
|
// Edit Display Layout
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -101,17 +112,21 @@ test.describe('Display Layout', () => {
|
|||||||
// On getting data, check if the value found in the Display Layout is the most recent value
|
// On getting data, check if the value found in the Display Layout is the most recent value
|
||||||
// from the Sine Wave Generator
|
// from the Sine Wave Generator
|
||||||
const formattedTelemetryValue = getTelemValuePromise;
|
const formattedTelemetryValue = getTelemValuePromise;
|
||||||
const displayLayoutValuePromise = await page.waitForSelector(`text="${formattedTelemetryValue}"`);
|
const displayLayoutValuePromise = await page.waitForSelector(
|
||||||
|
`text="${formattedTelemetryValue}"`
|
||||||
|
);
|
||||||
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
const displayLayoutValue = await displayLayoutValuePromise.textContent();
|
||||||
const trimmedDisplayValue = displayLayoutValue.trim();
|
const trimmedDisplayValue = displayLayoutValue.trim();
|
||||||
|
|
||||||
expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
expect(trimmedDisplayValue).toBe(formattedTelemetryValue);
|
||||||
});
|
});
|
||||||
test('items in a display layout can be removed with object tree context menu when viewing the display layout', async ({ page }) => {
|
test('items in a display layout can be removed with object tree context menu when viewing the display layout', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create a Display Layout
|
// Create a Display Layout
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Display Layout',
|
type: 'Display Layout',
|
||||||
name: "Test Display Layout"
|
name: 'Test Display Layout'
|
||||||
});
|
});
|
||||||
// Edit Display Layout
|
// Edit Display Layout
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -144,7 +159,9 @@ test.describe('Display Layout', () => {
|
|||||||
|
|
||||||
expect(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
expect(await page.locator('.l-layout .l-layout__frame').count()).toEqual(0);
|
||||||
});
|
});
|
||||||
test('items in a display layout can be removed with object tree context menu when viewing another item', async ({ page }) => {
|
test('items in a display layout can be removed with object tree context menu when viewing another item', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/3117'
|
description: 'https://github.com/nasa/openmct/issues/3117'
|
||||||
@ -200,7 +217,9 @@ test.describe('Display Layout', () => {
|
|||||||
* @returns {Promise<string>} the formatted sin telemetry value
|
* @returns {Promise<string>} the formatted sin telemetry value
|
||||||
*/
|
*/
|
||||||
async function subscribeToTelemetry(page, objectIdentifier) {
|
async function subscribeToTelemetry(page, objectIdentifier) {
|
||||||
const getTelemValuePromise = new Promise(resolve => page.exposeFunction('getTelemValue', resolve));
|
const getTelemValuePromise = new Promise((resolve) =>
|
||||||
|
page.exposeFunction('getTelemValue', resolve)
|
||||||
|
);
|
||||||
|
|
||||||
await page.evaluate(async (telemetryIdentifier) => {
|
await page.evaluate(async (telemetryIdentifier) => {
|
||||||
const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
|
const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
|
||||||
|
@ -36,29 +36,45 @@ test.describe('The Fault Management Plugin using example faults', () => {
|
|||||||
expect.soft(faultCount).toEqual(criticalityIconCount);
|
expect.soft(faultCount).toEqual(criticalityIconCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('When selecting a fault, it has an "is-selected" class and it\'s information shows in the inspector @unstable', async ({ page }) => {
|
test('When selecting a fault, it has an "is-selected" class and it\'s information shows in the inspector @unstable', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
await utils.selectFaultItem(page, 1);
|
await utils.selectFaultItem(page, 1);
|
||||||
|
|
||||||
await selectInspectorTab(page, 'Fault Management Configuration');
|
await selectInspectorTab(page, 'Fault Management Configuration');
|
||||||
const selectedFaultName = await page.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname').textContent();
|
const selectedFaultName = await page
|
||||||
const inspectorFaultNameCount = await page.locator(`.c-inspector__properties >> :text("${selectedFaultName}")`).count();
|
.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname')
|
||||||
|
.textContent();
|
||||||
|
const inspectorFaultNameCount = await page
|
||||||
|
.locator(`.c-inspector__properties >> :text("${selectedFaultName}")`)
|
||||||
|
.count();
|
||||||
|
|
||||||
await expect.soft(page.locator('.c-faults-list-view-item-body > .c-fault-mgmt__list').first()).toHaveClass(/is-selected/);
|
await expect
|
||||||
|
.soft(page.locator('.c-faults-list-view-item-body > .c-fault-mgmt__list').first())
|
||||||
|
.toHaveClass(/is-selected/);
|
||||||
expect.soft(inspectorFaultNameCount).toEqual(1);
|
expect.soft(inspectorFaultNameCount).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('When selecting multiple faults, no specific fault information is shown in the inspector @unstable', async ({ page }) => {
|
test('When selecting multiple faults, no specific fault information is shown in the inspector @unstable', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
await utils.selectFaultItem(page, 1);
|
await utils.selectFaultItem(page, 1);
|
||||||
await utils.selectFaultItem(page, 2);
|
await utils.selectFaultItem(page, 2);
|
||||||
|
|
||||||
const selectedRows = page.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname');
|
const selectedRows = page.locator(
|
||||||
|
'.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname'
|
||||||
|
);
|
||||||
expect.soft(await selectedRows.count()).toEqual(2);
|
expect.soft(await selectedRows.count()).toEqual(2);
|
||||||
|
|
||||||
await selectInspectorTab(page, 'Fault Management Configuration');
|
await selectInspectorTab(page, 'Fault Management Configuration');
|
||||||
const firstSelectedFaultName = await selectedRows.nth(0).textContent();
|
const firstSelectedFaultName = await selectedRows.nth(0).textContent();
|
||||||
const secondSelectedFaultName = await selectedRows.nth(1).textContent();
|
const secondSelectedFaultName = await selectedRows.nth(1).textContent();
|
||||||
const firstNameInInspectorCount = await page.locator(`.c-inspector__properties >> :text("${firstSelectedFaultName}")`).count();
|
const firstNameInInspectorCount = await page
|
||||||
const secondNameInInspectorCount = await page.locator(`.c-inspector__properties >> :text("${secondSelectedFaultName}")`).count();
|
.locator(`.c-inspector__properties >> :text("${firstSelectedFaultName}")`)
|
||||||
|
.count();
|
||||||
|
const secondNameInInspectorCount = await page
|
||||||
|
.locator(`.c-inspector__properties >> :text("${secondSelectedFaultName}")`)
|
||||||
|
.count();
|
||||||
|
|
||||||
expect.soft(firstNameInInspectorCount).toEqual(0);
|
expect.soft(firstNameInInspectorCount).toEqual(0);
|
||||||
expect.soft(secondNameInInspectorCount).toEqual(0);
|
expect.soft(secondNameInInspectorCount).toEqual(0);
|
||||||
@ -208,7 +224,6 @@ test.describe('The Fault Management Plugin using example faults', () => {
|
|||||||
expect.soft(sortedHighestSeverity).toEqual(highestSeverity);
|
expect.soft(sortedHighestSeverity).toEqual(highestSeverity);
|
||||||
expect.soft(sortedLowestSeverity).toEqual(lowestSeverity);
|
expect.soft(sortedLowestSeverity).toEqual(lowestSeverity);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('The Fault Management Plugin without using example faults', () => {
|
test.describe('The Fault Management Plugin without using example faults', () => {
|
||||||
|
@ -39,7 +39,9 @@ test.describe('Flexible Layout', () => {
|
|||||||
type: 'Clock'
|
type: 'Clock'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({ page }) => {
|
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
@ -62,7 +64,9 @@ test.describe('Flexible Layout', () => {
|
|||||||
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first());
|
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first());
|
||||||
await clockTreeItem.dragTo(page.locator('.c-fl__container.is-empty'));
|
await clockTreeItem.dragTo(page.locator('.c-fl__container.is-empty'));
|
||||||
// Check that panes can be dragged while Flexible Layout is in Edit mode
|
// Check that panes can be dragged while Flexible Layout is in Edit mode
|
||||||
let dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
let dragWrapper = page
|
||||||
|
.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper')
|
||||||
|
.first();
|
||||||
await expect(dragWrapper).toHaveAttribute('draggable', 'true');
|
await expect(dragWrapper).toHaveAttribute('draggable', 'true');
|
||||||
// Save Flexible Layout
|
// Save Flexible Layout
|
||||||
await page.locator('button[title="Save"]').click();
|
await page.locator('button[title="Save"]').click();
|
||||||
@ -71,7 +75,9 @@ test.describe('Flexible Layout', () => {
|
|||||||
dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||||
await expect(dragWrapper).toHaveAttribute('draggable', 'false');
|
await expect(dragWrapper).toHaveAttribute('draggable', 'false');
|
||||||
});
|
});
|
||||||
test('items in a flexible layout can be removed with object tree context menu when viewing the flexible layout', async ({ page }) => {
|
test('items in a flexible layout can be removed with object tree context menu when viewing the flexible layout', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const treePane = page.getByRole('tree', {
|
const treePane = page.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
});
|
});
|
||||||
@ -105,7 +111,9 @@ test.describe('Flexible Layout', () => {
|
|||||||
// Verify that the item has been removed from the layout
|
// Verify that the item has been removed from the layout
|
||||||
expect(await page.locator('.c-fl-container__frame').count()).toEqual(0);
|
expect(await page.locator('.c-fl-container__frame').count()).toEqual(0);
|
||||||
});
|
});
|
||||||
test('items in a flexible layout can be removed with object tree context menu when viewing another item', async ({ page }) => {
|
test('items in a flexible layout can be removed with object tree context menu when viewing another item', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/3117'
|
description: 'https://github.com/nasa/openmct/issues/3117'
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite is dedicated to testing the Gauge component.
|
* This test suite is dedicated to testing the Gauge component.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
@ -63,7 +63,13 @@ test.describe('Gauge', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Verify that the 'Replace telemetry source' modal appears and accept it
|
// Verify that the 'Replace telemetry source' modal appears and accept it
|
||||||
await expect.soft(page.locator('text=This action will replace the current telemetry source. Do you want to continue?')).toBeVisible();
|
await expect
|
||||||
|
.soft(
|
||||||
|
page.locator(
|
||||||
|
'text=This action will replace the current telemetry source. Do you want to continue?'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toBeVisible();
|
||||||
await page.click('text=Ok');
|
await page.click('text=Ok');
|
||||||
|
|
||||||
// Navigate to the gauge and verify that the new SWG
|
// Navigate to the gauge and verify that the new SWG
|
||||||
@ -81,7 +87,13 @@ test.describe('Gauge', () => {
|
|||||||
await page.locator('li[title="Remove this object from its containing object."]').click();
|
await page.locator('li[title="Remove this object from its containing object."]').click();
|
||||||
|
|
||||||
// Verify that the 'Remove object' confirmation modal appears and accept it
|
// Verify that the 'Remove object' confirmation modal appears and accept it
|
||||||
await expect.soft(page.locator('text=Warning! This action will remove this object. Are you sure you want to continue?')).toBeVisible();
|
await expect
|
||||||
|
.soft(
|
||||||
|
page.locator(
|
||||||
|
'text=Warning! This action will remove this object. Are you sure you want to continue?'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toBeVisible();
|
||||||
await page.click('text=Ok');
|
await page.click('text=Ok');
|
||||||
|
|
||||||
// Verify that the elements pool shows no elements
|
// Verify that the elements pool shows no elements
|
||||||
|
@ -44,7 +44,7 @@ test.describe('Example Imagery Object', () => {
|
|||||||
|
|
||||||
// Verify that the created object is focused
|
// Verify that the created object is focused
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
await page.locator(backgroundImageSelector).hover({ trial: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
|
test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
|
||||||
@ -55,7 +55,10 @@ test.describe('Example Imagery Object', () => {
|
|||||||
await mouseZoomOnImageAndAssert(page, -2);
|
await mouseZoomOnImageAndAssert(page, -2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can adjust image brightness/contrast by dragging the sliders', async ({ page, browserName }) => {
|
test('Can adjust image brightness/contrast by dragging the sliders', async ({
|
||||||
|
page,
|
||||||
|
browserName
|
||||||
|
}) => {
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(browserName === 'firefox', 'This test needs to be updated to work with firefox');
|
test.skip(browserName === 'firefox', 'This test needs to be updated to work with firefox');
|
||||||
// Open the image filter menu
|
// Open the image filter menu
|
||||||
@ -69,11 +72,11 @@ test.describe('Example Imagery Object', () => {
|
|||||||
test('Can use alt+drag to move around image once zoomed in', async ({ page }) => {
|
test('Can use alt+drag to move around image once zoomed in', async ({ page }) => {
|
||||||
const deltaYStep = 100; //equivalent to 1x zoom
|
const deltaYStep = 100; //equivalent to 1x zoom
|
||||||
|
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
await page.locator(backgroundImageSelector).hover({ trial: true });
|
||||||
|
|
||||||
// zoom in
|
// zoom in
|
||||||
await page.mouse.wheel(0, deltaYStep * 2);
|
await page.mouse.wheel(0, deltaYStep * 2);
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
await page.locator(backgroundImageSelector).hover({ trial: true });
|
||||||
const zoomedBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const zoomedBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2;
|
const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2;
|
||||||
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
||||||
@ -91,42 +94,41 @@ test.describe('Example Imagery Object', () => {
|
|||||||
expect(expectedAltText).toEqual(imageryHintsText);
|
expect(expectedAltText).toEqual(imageryHintsText);
|
||||||
|
|
||||||
// pan right
|
// pan right
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX - 200, imageCenterY, 10);
|
await page.mouse.move(imageCenterX - 200, imageCenterY, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterRightPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterRightPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(zoomedBoundingBox.x).toBeGreaterThan(afterRightPanBoundingBox.x);
|
expect(zoomedBoundingBox.x).toBeGreaterThan(afterRightPanBoundingBox.x);
|
||||||
|
|
||||||
// pan left
|
// pan left
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY, 10);
|
await page.mouse.move(imageCenterX, imageCenterY, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterLeftPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterLeftPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterRightPanBoundingBox.x).toBeLessThan(afterLeftPanBoundingBox.x);
|
expect(afterRightPanBoundingBox.x).toBeLessThan(afterLeftPanBoundingBox.x);
|
||||||
|
|
||||||
// pan up
|
// pan up
|
||||||
await page.mouse.move(imageCenterX, imageCenterY);
|
await page.mouse.move(imageCenterX, imageCenterY);
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY + 200, 10);
|
await page.mouse.move(imageCenterX, imageCenterY + 200, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterUpPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterUpPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterUpPanBoundingBox.y).toBeGreaterThan(afterLeftPanBoundingBox.y);
|
expect(afterUpPanBoundingBox.y).toBeGreaterThan(afterLeftPanBoundingBox.y);
|
||||||
|
|
||||||
// pan down
|
// pan down
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY - 200, 10);
|
await page.mouse.move(imageCenterX, imageCenterY - 200, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterDownPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterDownPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterDownPanBoundingBox.y).toBeLessThan(afterUpPanBoundingBox.y);
|
expect(afterDownPanBoundingBox.y).toBeLessThan(afterUpPanBoundingBox.y);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can use + - buttons to zoom on the image @unstable', async ({ page }) => {
|
test('Can use + - buttons to zoom on the image @unstable', async ({ page }) => {
|
||||||
@ -134,7 +136,7 @@ test.describe('Example Imagery Object', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can use the reset button to reset the image @unstable', async ({ page }, testInfo) => {
|
test('Can use the reset button to reset the image @unstable', async ({ page }, testInfo) => {
|
||||||
test.slow(testInfo.project === 'chrome-beta', "This test is slow in chrome-beta");
|
test.slow(testInfo.project === 'chrome-beta', 'This test is slow in chrome-beta');
|
||||||
// Get initial image dimensions
|
// Get initial image dimensions
|
||||||
const initialBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const initialBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
|
|
||||||
@ -196,18 +198,22 @@ test.describe('Example Imagery in Display Layout', () => {
|
|||||||
|
|
||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.click('button:has-text("OK")'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(
|
||||||
|
'Unnamed Example Imagery'
|
||||||
|
);
|
||||||
|
|
||||||
await page.goto(displayLayout.url);
|
await page.goto(displayLayout.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('View Large action pauses imagery when in realtime and returns to realtime', async ({ page }) => {
|
test('View Large action pauses imagery when in realtime and returns to realtime', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/3647'
|
description: 'https://github.com/nasa/openmct/issues/3647'
|
||||||
@ -335,13 +341,15 @@ test.describe('Example Imagery in Flexible layout', () => {
|
|||||||
|
|
||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.click('button:has-text("OK")'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(
|
||||||
|
'Unnamed Example Imagery'
|
||||||
|
);
|
||||||
|
|
||||||
await page.goto(flexibleLayout.url);
|
await page.goto(flexibleLayout.url);
|
||||||
});
|
});
|
||||||
@ -377,13 +385,15 @@ test.describe('Example Imagery in Tabs View', () => {
|
|||||||
|
|
||||||
// Click text=OK
|
// Click text=OK
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.click('button:has-text("OK")'),
|
page.click('button:has-text("OK")'),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText(
|
||||||
|
'Unnamed Example Imagery'
|
||||||
|
);
|
||||||
|
|
||||||
await page.goto(tabsView.url);
|
await page.goto(tabsView.url);
|
||||||
});
|
});
|
||||||
@ -417,7 +427,9 @@ test.describe('Example Imagery in Time Strip', () => {
|
|||||||
await page.locator('.c-imagery-tsv-container').hover();
|
await page.locator('.c-imagery-tsv-container').hover();
|
||||||
|
|
||||||
// Get the img src of the hovered image thumbnail
|
// Get the img src of the hovered image thumbnail
|
||||||
const hoveredThumbnailImg = page.locator('.c-imagery-tsv div.c-imagery-tsv__image-wrapper:hover img');
|
const hoveredThumbnailImg = page.locator(
|
||||||
|
'.c-imagery-tsv div.c-imagery-tsv__image-wrapper:hover img'
|
||||||
|
);
|
||||||
const hoveredThumbnailImgSrc = await hoveredThumbnailImg.getAttribute('src');
|
const hoveredThumbnailImgSrc = await hoveredThumbnailImg.getAttribute('src');
|
||||||
|
|
||||||
// Verify that imagery timestrip view uses the thumbnailUrl as img src for thumbnails
|
// Verify that imagery timestrip view uses the thumbnailUrl as img src for thumbnails
|
||||||
@ -496,14 +508,19 @@ async function performImageryViewOperationsAndAssert(page) {
|
|||||||
|
|
||||||
// The imagery view should be updated when new images come in
|
// The imagery view should be updated when new images come in
|
||||||
const imageCount = await page.locator('.c-imagery__thumb').count();
|
const imageCount = await page.locator('.c-imagery__thumb').count();
|
||||||
await expect.poll(async () => {
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () => {
|
||||||
const newImageCount = await page.locator('.c-imagery__thumb').count();
|
const newImageCount = await page.locator('.c-imagery__thumb').count();
|
||||||
|
|
||||||
return newImageCount;
|
return newImageCount;
|
||||||
}, {
|
},
|
||||||
message: "verify that old images are discarded",
|
{
|
||||||
|
message: 'verify that old images are discarded',
|
||||||
timeout: 7 * 1000
|
timeout: 7 * 1000
|
||||||
}).toBe(imageCount);
|
}
|
||||||
|
)
|
||||||
|
.toBe(imageCount);
|
||||||
|
|
||||||
// Verify selected image is still displayed
|
// Verify selected image is still displayed
|
||||||
await expect(selectedImage).toBeVisible();
|
await expect(selectedImage).toBeVisible();
|
||||||
@ -532,7 +549,7 @@ async function dragBrightnessSliderAndAssertFilterValues(page) {
|
|||||||
const brightnessMidX = brightnessBoundingBox.x + brightnessBoundingBox.width / 2;
|
const brightnessMidX = brightnessBoundingBox.x + brightnessBoundingBox.width / 2;
|
||||||
const brightnessMidY = brightnessBoundingBox.y + brightnessBoundingBox.height / 2;
|
const brightnessMidY = brightnessBoundingBox.y + brightnessBoundingBox.height / 2;
|
||||||
|
|
||||||
await page.locator(brightnessSlider).hover({trial: true});
|
await page.locator(brightnessSlider).hover({ trial: true });
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(brightnessBoundingBox.x + brightnessBoundingBox.width, brightnessMidY);
|
await page.mouse.move(brightnessBoundingBox.x + brightnessBoundingBox.width, brightnessMidY);
|
||||||
await assertBackgroundImageBrightness(page, '500');
|
await assertBackgroundImageBrightness(page, '500');
|
||||||
@ -553,7 +570,7 @@ async function dragContrastSliderAndAssertFilterValues(page) {
|
|||||||
const contrastMidX = contrastBoundingBox.x + contrastBoundingBox.width / 2;
|
const contrastMidX = contrastBoundingBox.x + contrastBoundingBox.width / 2;
|
||||||
const contrastMidY = contrastBoundingBox.y + contrastBoundingBox.height / 2;
|
const contrastMidY = contrastBoundingBox.y + contrastBoundingBox.height / 2;
|
||||||
|
|
||||||
await page.locator(contrastSlider).hover({trial: true});
|
await page.locator(contrastSlider).hover({ trial: true });
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(contrastBoundingBox.x + contrastBoundingBox.width, contrastMidY);
|
await page.mouse.move(contrastBoundingBox.x + contrastBoundingBox.width, contrastMidY);
|
||||||
await assertBackgroundImageContrast(page, '500');
|
await assertBackgroundImageContrast(page, '500');
|
||||||
@ -586,24 +603,35 @@ async function assertBackgroundImageBrightness(page, expected) {
|
|||||||
async function assertBackgroundImageUrlFromBackgroundCss(page) {
|
async function assertBackgroundImageUrlFromBackgroundCss(page) {
|
||||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||||
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
||||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
return window
|
||||||
|
.getComputedStyle(el)
|
||||||
|
.getPropertyValue('background-image')
|
||||||
|
.match(/url\(([^)]+)\)/)[1];
|
||||||
});
|
});
|
||||||
let backgroundImageUrl1 = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
let backgroundImageUrl1 = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
||||||
console.log('backgroundImageUrl1 ' + backgroundImageUrl1);
|
console.log('backgroundImageUrl1 ' + backgroundImageUrl1);
|
||||||
|
|
||||||
let backgroundImageUrl2;
|
let backgroundImageUrl2;
|
||||||
await expect.poll(async () => {
|
await expect
|
||||||
|
.poll(
|
||||||
|
async () => {
|
||||||
// Verify next image has updated
|
// Verify next image has updated
|
||||||
let backgroundImageUrlNext = await backgroundImage.evaluate((el) => {
|
let backgroundImageUrlNext = await backgroundImage.evaluate((el) => {
|
||||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
return window
|
||||||
|
.getComputedStyle(el)
|
||||||
|
.getPropertyValue('background-image')
|
||||||
|
.match(/url\(([^)]+)\)/)[1];
|
||||||
});
|
});
|
||||||
backgroundImageUrl2 = backgroundImageUrlNext.slice(1, -1); //forgive me, padre
|
backgroundImageUrl2 = backgroundImageUrlNext.slice(1, -1); //forgive me, padre
|
||||||
|
|
||||||
return backgroundImageUrl2;
|
return backgroundImageUrl2;
|
||||||
}, {
|
},
|
||||||
message: "verify next image has updated",
|
{
|
||||||
|
message: 'verify next image has updated',
|
||||||
timeout: 7 * 1000
|
timeout: 7 * 1000
|
||||||
}).not.toBe(backgroundImageUrl1);
|
}
|
||||||
|
)
|
||||||
|
.not.toBe(backgroundImageUrl1);
|
||||||
console.log('backgroundImageUrl2 ' + backgroundImageUrl2);
|
console.log('backgroundImageUrl2 ' + backgroundImageUrl2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,39 +646,39 @@ async function panZoomAndAssertImageProperties(page) {
|
|||||||
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2;
|
||||||
|
|
||||||
// Pan right
|
// Pan right
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX - 200, imageCenterY, 10);
|
await page.mouse.move(imageCenterX - 200, imageCenterY, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterRightPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterRightPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(zoomedBoundingBox.x).toBeGreaterThan(afterRightPanBoundingBox.x);
|
expect(zoomedBoundingBox.x).toBeGreaterThan(afterRightPanBoundingBox.x);
|
||||||
|
|
||||||
// Pan left
|
// Pan left
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY, 10);
|
await page.mouse.move(imageCenterX, imageCenterY, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterLeftPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterLeftPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterRightPanBoundingBox.x).toBeLessThan(afterLeftPanBoundingBox.x);
|
expect(afterRightPanBoundingBox.x).toBeLessThan(afterLeftPanBoundingBox.x);
|
||||||
|
|
||||||
// Pan up
|
// Pan up
|
||||||
await page.mouse.move(imageCenterX, imageCenterY);
|
await page.mouse.move(imageCenterX, imageCenterY);
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY + 200, 10);
|
await page.mouse.move(imageCenterX, imageCenterY + 200, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterUpPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterUpPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterUpPanBoundingBox.y).toBeGreaterThanOrEqual(afterLeftPanBoundingBox.y);
|
expect(afterUpPanBoundingBox.y).toBeGreaterThanOrEqual(afterLeftPanBoundingBox.y);
|
||||||
|
|
||||||
// Pan down
|
// Pan down
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.down(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.down(x)));
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(imageCenterX, imageCenterY - 200, 10);
|
await page.mouse.move(imageCenterX, imageCenterY - 200, 10);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
await Promise.all(panHotkey.map(x => page.keyboard.up(x)));
|
await Promise.all(panHotkey.map((x) => page.keyboard.up(x)));
|
||||||
const afterDownPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const afterDownPanBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
expect(afterDownPanBoundingBox.y).toBeLessThanOrEqual(afterUpPanBoundingBox.y);
|
expect(afterDownPanBoundingBox.y).toBeLessThanOrEqual(afterUpPanBoundingBox.y);
|
||||||
}
|
}
|
||||||
@ -660,11 +688,11 @@ async function panZoomAndAssertImageProperties(page) {
|
|||||||
* has successfully zoomed in or out.
|
* has successfully zoomed in or out.
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
* @param {number} [factor = 2] The zoom factor. Positive for zoom in, negative for zoom out.
|
* @param {number} [factor = 2] The zoom factor. Positive for zoom in, negative for zoom out.
|
||||||
*/
|
*/
|
||||||
async function mouseZoomOnImageAndAssert(page, factor = 2) {
|
async function mouseZoomOnImageAndAssert(page, factor = 2) {
|
||||||
// Zoom in
|
// Zoom in
|
||||||
const originalImageDimensions = await page.locator(backgroundImageSelector).boundingBox();
|
const originalImageDimensions = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
await page.locator(backgroundImageSelector).hover({ trial: true });
|
||||||
const deltaYStep = 100; // equivalent to 1x zoom
|
const deltaYStep = 100; // equivalent to 1x zoom
|
||||||
await page.mouse.wheel(0, deltaYStep * factor);
|
await page.mouse.wheel(0, deltaYStep * factor);
|
||||||
const zoomedBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
const zoomedBoundingBox = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
@ -675,7 +703,7 @@ async function mouseZoomOnImageAndAssert(page, factor = 2) {
|
|||||||
await page.mouse.move(imageCenterX, imageCenterY);
|
await page.mouse.move(imageCenterX, imageCenterY);
|
||||||
|
|
||||||
// Wait for zoom animation to finish
|
// Wait for zoom animation to finish
|
||||||
await page.locator(backgroundImageSelector).hover({trial: true});
|
await page.locator(backgroundImageSelector).hover({ trial: true });
|
||||||
const imageMouseZoomed = await page.locator(backgroundImageSelector).boundingBox();
|
const imageMouseZoomed = await page.locator(backgroundImageSelector).boundingBox();
|
||||||
|
|
||||||
if (factor > 0) {
|
if (factor > 0) {
|
||||||
@ -742,10 +770,12 @@ async function assertBackgroundImageContrast(page, expected) {
|
|||||||
*/
|
*/
|
||||||
async function zoomIntoImageryByButton(page) {
|
async function zoomIntoImageryByButton(page) {
|
||||||
// FIXME: There should only be one set of imagery buttons, but there are two?
|
// FIXME: There should only be one set of imagery buttons, but there are two?
|
||||||
const zoomInBtn = page.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-in").nth(0);
|
const zoomInBtn = page
|
||||||
|
.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-in")
|
||||||
|
.nth(0);
|
||||||
const backgroundImage = page.locator(backgroundImageSelector);
|
const backgroundImage = page.locator(backgroundImageSelector);
|
||||||
if (!(await zoomInBtn.isVisible())) {
|
if (!(await zoomInBtn.isVisible())) {
|
||||||
await backgroundImage.hover({trial: true});
|
await backgroundImage.hover({ trial: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
await zoomInBtn.click();
|
await zoomInBtn.click();
|
||||||
@ -759,10 +789,12 @@ async function zoomIntoImageryByButton(page) {
|
|||||||
*/
|
*/
|
||||||
async function zoomOutOfImageryByButton(page) {
|
async function zoomOutOfImageryByButton(page) {
|
||||||
// FIXME: There should only be one set of imagery buttons, but there are two?
|
// FIXME: There should only be one set of imagery buttons, but there are two?
|
||||||
const zoomOutBtn = page.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-out").nth(0);
|
const zoomOutBtn = page
|
||||||
|
.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-out")
|
||||||
|
.nth(0);
|
||||||
const backgroundImage = page.locator(backgroundImageSelector);
|
const backgroundImage = page.locator(backgroundImageSelector);
|
||||||
if (!(await zoomOutBtn.isVisible())) {
|
if (!(await zoomOutBtn.isVisible())) {
|
||||||
await backgroundImage.hover({trial: true});
|
await backgroundImage.hover({ trial: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
await zoomOutBtn.click();
|
await zoomOutBtn.click();
|
||||||
@ -776,10 +808,12 @@ async function zoomOutOfImageryByButton(page) {
|
|||||||
*/
|
*/
|
||||||
async function resetImageryPanAndZoom(page) {
|
async function resetImageryPanAndZoom(page) {
|
||||||
// FIXME: There should only be one set of imagery buttons, but there are two?
|
// FIXME: There should only be one set of imagery buttons, but there are two?
|
||||||
const panZoomResetBtn = page.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-reset").nth(0);
|
const panZoomResetBtn = page
|
||||||
|
.locator("[role='toolbar'][aria-label='Image controls'] .t-btn-zoom-reset")
|
||||||
|
.nth(0);
|
||||||
const backgroundImage = page.locator(backgroundImageSelector);
|
const backgroundImage = page.locator(backgroundImageSelector);
|
||||||
if (!(await panZoomResetBtn.isVisible())) {
|
if (!(await panZoomResetBtn.isVisible())) {
|
||||||
await backgroundImage.hover({trial: true});
|
await backgroundImage.hover({ trial: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
await panZoomResetBtn.click();
|
await panZoomResetBtn.click();
|
||||||
|
@ -29,22 +29,31 @@ This test suite is dedicated to tests which verify the basic operations surround
|
|||||||
const { test, expect } = require('../../../../baseFixtures');
|
const { test, expect } = require('../../../../baseFixtures');
|
||||||
|
|
||||||
test.describe('ExportAsJSON', () => {
|
test.describe('ExportAsJSON', () => {
|
||||||
test.fixme('Create a basic object and verify that it can be exported as JSON from Tree', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Create a basic object and verify that it can be exported as JSON from Tree',
|
||||||
|
async ({ page }) => {
|
||||||
//Create domain object
|
//Create domain object
|
||||||
//Save Domain Object
|
//Save Domain Object
|
||||||
//Verify that the newly created domain object can be exported as JSON from the Tree
|
//Verify that the newly created domain object can be exported as JSON from the Tree
|
||||||
});
|
}
|
||||||
test.fixme('Create a basic object and verify that it can be exported as JSON from 3 dot menu', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'Create a basic object and verify that it can be exported as JSON from 3 dot menu',
|
||||||
|
async ({ page }) => {
|
||||||
//Create domain object
|
//Create domain object
|
||||||
//Save Domain Object
|
//Save Domain Object
|
||||||
//Verify that the newly created domain object can be exported as JSON from the 3 dot menu
|
//Verify that the newly created domain object can be exported as JSON from the 3 dot menu
|
||||||
});
|
}
|
||||||
|
);
|
||||||
test.fixme('Verify that a nested Object can be exported as JSON', async ({ page }) => {
|
test.fixme('Verify that a nested Object can be exported as JSON', async ({ page }) => {
|
||||||
// Create 2 objects with hierarchy
|
// Create 2 objects with hierarchy
|
||||||
// Export as JSON
|
// Export as JSON
|
||||||
// Verify Hiearchy
|
// Verify Hiearchy
|
||||||
});
|
});
|
||||||
test.fixme('Verify that the ExportAsJSON dropdown does not appear for the item X', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Verify that the ExportAsJSON dropdown does not appear for the item X',
|
||||||
|
async ({ page }) => {
|
||||||
// Other than non-persistible objects
|
// Other than non-persistible objects
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -33,16 +33,22 @@ test.describe('ExportAsJSON', () => {
|
|||||||
//Verify that an testdata JSON file can be imported from Tree
|
//Verify that an testdata JSON file can be imported from Tree
|
||||||
//Verify correctness of imported domain object
|
//Verify correctness of imported domain object
|
||||||
});
|
});
|
||||||
test.fixme('Verify that domain object can be importAsJSON from 3 dot menu on folder', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Verify that domain object can be importAsJSON from 3 dot menu on folder',
|
||||||
|
async ({ page }) => {
|
||||||
//Verify that an testdata JSON file can be imported from 3 dot menu on folder domain object
|
//Verify that an testdata JSON file can be imported from 3 dot menu on folder domain object
|
||||||
//Verify correctness of imported domain object
|
//Verify correctness of imported domain object
|
||||||
});
|
}
|
||||||
|
);
|
||||||
test.fixme('Verify that a nested Objects can be importAsJSON', async ({ page }) => {
|
test.fixme('Verify that a nested Objects can be importAsJSON', async ({ page }) => {
|
||||||
// Testdata with hierarchy
|
// Testdata with hierarchy
|
||||||
// ImportAsJSON on Tree
|
// ImportAsJSON on Tree
|
||||||
// Verify Hierarchy
|
// Verify Hierarchy
|
||||||
});
|
});
|
||||||
test.fixme('Verify that the ImportAsJSON dropdown does not appear for the item X', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Verify that the ImportAsJSON dropdown does not appear for the item X',
|
||||||
|
async ({ page }) => {
|
||||||
// Other than non-persistible objects
|
// Other than non-persistible objects
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,13 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, setStartOffset, setFixedTimeMode, setRealTimeMode, selectInspectorTab } = require('../../../../appActions');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
setStartOffset,
|
||||||
|
setFixedTimeMode,
|
||||||
|
setRealTimeMode,
|
||||||
|
selectInspectorTab
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Testing LAD table configuration', () => {
|
test.describe('Testing LAD table configuration', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
@ -30,13 +36,13 @@ test.describe('Testing LAD table configuration', () => {
|
|||||||
// Create LAD table
|
// Create LAD table
|
||||||
const ladTable = await createDomainObjectWithDefaults(page, {
|
const ladTable = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'LAD Table',
|
type: 'LAD Table',
|
||||||
name: "Test LAD Table"
|
name: 'Test LAD Table'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create Sine Wave Generator
|
// Create Sine Wave Generator
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
name: "Test Sine Wave Generator",
|
name: 'Test Sine Wave Generator',
|
||||||
parent: ladTable.uuid
|
parent: ladTable.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -117,7 +123,9 @@ test.describe('Testing LAD table configuration', () => {
|
|||||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('LAD Tables don\'t allow selection of rows but does show context click menus', async ({ page }) => {
|
test("LAD Tables don't allow selection of rows but does show context click menus", async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const cell = await page.locator('.js-first-data');
|
const cell = await page.locator('.js-first-data');
|
||||||
const userSelectable = await cell.evaluate((el) => {
|
const userSelectable = await cell.evaluate((el) => {
|
||||||
return window.getComputedStyle(el).getPropertyValue('user-select');
|
return window.getComputedStyle(el).getPropertyValue('user-select');
|
||||||
@ -145,14 +153,16 @@ test.describe('Testing LAD table @unstable', () => {
|
|||||||
// Create Sine Wave Generator
|
// Create Sine Wave Generator
|
||||||
sineWaveObject = await createDomainObjectWithDefaults(page, {
|
sineWaveObject = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
name: "Test Sine Wave Generator"
|
name: 'Test Sine Wave Generator'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('telemetry value exactly matches latest telemetry value received in real time', async ({ page }) => {
|
test('telemetry value exactly matches latest telemetry value received in real time', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create LAD table
|
// Create LAD table
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'LAD Table',
|
type: 'LAD Table',
|
||||||
name: "Test LAD Table"
|
name: 'Test LAD Table'
|
||||||
});
|
});
|
||||||
// Edit LAD table
|
// Edit LAD table
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -174,11 +184,13 @@ test.describe('Testing LAD table @unstable', () => {
|
|||||||
|
|
||||||
expect(ladTableValue).toBe(subscribeTelemValue);
|
expect(ladTableValue).toBe(subscribeTelemValue);
|
||||||
});
|
});
|
||||||
test('telemetry value exactly matches latest telemetry value received in fixed time', async ({ page }) => {
|
test('telemetry value exactly matches latest telemetry value received in fixed time', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create LAD table
|
// Create LAD table
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'LAD Table',
|
type: 'LAD Table',
|
||||||
name: "Test LAD Table"
|
name: 'Test LAD Table'
|
||||||
});
|
});
|
||||||
// Edit LAD table
|
// Edit LAD table
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -216,7 +228,9 @@ test.describe('Testing LAD table @unstable', () => {
|
|||||||
* @returns {Promise<string>} the formatted sin telemetry value
|
* @returns {Promise<string>} the formatted sin telemetry value
|
||||||
*/
|
*/
|
||||||
async function subscribeToTelemetry(page, objectIdentifier) {
|
async function subscribeToTelemetry(page, objectIdentifier) {
|
||||||
const getTelemValuePromise = new Promise(resolve => page.exposeFunction('getTelemValue', resolve));
|
const getTelemValuePromise = new Promise((resolve) =>
|
||||||
|
page.exposeFunction('getTelemValue', resolve)
|
||||||
|
);
|
||||||
|
|
||||||
await page.evaluate(async (telemetryIdentifier) => {
|
await page.evaluate(async (telemetryIdentifier) => {
|
||||||
const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
|
const telemetryObject = await window.openmct.objects.get(telemetryIdentifier);
|
||||||
|
@ -50,22 +50,31 @@ test.describe('Default Notebook', () => {
|
|||||||
// `JSON.parse(localStorage.getItem('notebook-storage'));`
|
// `JSON.parse(localStorage.getItem('notebook-storage'));`
|
||||||
// 1. - Clear default notebook:
|
// 1. - Clear default notebook:
|
||||||
// `localStorage.setItem('notebook-storage', null);`
|
// `localStorage.setItem('notebook-storage', null);`
|
||||||
test.fixme('A newly created Notebook is automatically set as the default notebook if no other notebooks exist', async ({ page }) => {
|
test.fixme(
|
||||||
|
'A newly created Notebook is automatically set as the default notebook if no other notebooks exist',
|
||||||
|
async ({ page }) => {
|
||||||
//Create new notebook
|
//Create new notebook
|
||||||
//Verify Default Notebook Characteristics
|
//Verify Default Notebook Characteristics
|
||||||
});
|
}
|
||||||
test.fixme('A newly created Notebook is automatically set as the default notebook if at least one other notebook exists', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'A newly created Notebook is automatically set as the default notebook if at least one other notebook exists',
|
||||||
|
async ({ page }) => {
|
||||||
//Create new notebook A
|
//Create new notebook A
|
||||||
//Create second notebook B
|
//Create second notebook B
|
||||||
//Verify Non-Default Notebook A Characteristics
|
//Verify Non-Default Notebook A Characteristics
|
||||||
//Verify Default Notebook B Characteristics
|
//Verify Default Notebook B Characteristics
|
||||||
});
|
}
|
||||||
test.fixme('If a default notebook is deleted, the second most recent notebook becomes the default', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'If a default notebook is deleted, the second most recent notebook becomes the default',
|
||||||
|
async ({ page }) => {
|
||||||
//Create new notebook A
|
//Create new notebook A
|
||||||
//Create second notebook B
|
//Create second notebook B
|
||||||
//Delete Notebook B
|
//Delete Notebook B
|
||||||
//Verify Default Notebook A Characteristics
|
//Verify Default Notebook A Characteristics
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Notebook section tests', () => {
|
test.describe('Notebook section tests', () => {
|
||||||
@ -79,7 +88,9 @@ test.describe('Notebook section tests', () => {
|
|||||||
type: NOTEBOOK_NAME
|
type: NOTEBOOK_NAME
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('Default and new sections are automatically named Unnamed Section with Unnamed Page', async ({ page }) => {
|
test('Default and new sections are automatically named Unnamed Section with Unnamed Page', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const notebookSectionNames = page.locator('.c-notebook__sections .c-list__item__name');
|
const notebookSectionNames = page.locator('.c-notebook__sections .c-list__item__name');
|
||||||
const notebookPageNames = page.locator('.c-notebook__pages .c-list__item__name');
|
const notebookPageNames = page.locator('.c-notebook__pages .c-list__item__name');
|
||||||
await expect(notebookSectionNames).toBeHidden();
|
await expect(notebookSectionNames).toBeHidden();
|
||||||
@ -104,7 +115,6 @@ test.describe('Notebook section tests', () => {
|
|||||||
const newPageName = await notebookPageNames.innerText();
|
const newPageName = await notebookPageNames.innerText();
|
||||||
await expect(notebookPageNames).toBeVisible();
|
await expect(notebookPageNames).toBeVisible();
|
||||||
expect(newPageName).toBe('Unnamed Page');
|
expect(newPageName).toBe('Unnamed Page');
|
||||||
|
|
||||||
});
|
});
|
||||||
test.fixme('Section selection operations and associated behavior', async ({ page }) => {
|
test.fixme('Section selection operations and associated behavior', async ({ page }) => {
|
||||||
//Create new notebook A
|
//Create new notebook A
|
||||||
@ -152,7 +162,9 @@ test.describe('Notebook page tests', () => {
|
|||||||
});
|
});
|
||||||
//Test will need to be implemented after a refactor in #5713
|
//Test will need to be implemented after a refactor in #5713
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip('Delete page popup is removed properly on clicking dropdown again', async ({ page }) => {
|
test.skip('Delete page popup is removed properly on clicking dropdown again', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5713'
|
description: 'https://github.com/nasa/openmct/issues/5713'
|
||||||
@ -252,7 +264,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
let notebookObject;
|
let notebookObject;
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../../../helper/', 'addInitNotebookWithUrls.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../../../helper/', 'addInitNotebookWithUrls.js')
|
||||||
|
});
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
notebookObject = await createDomainObjectWithDefaults(page, {
|
notebookObject = await createDomainObjectWithDefaults(page, {
|
||||||
@ -268,7 +282,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
await expect(page.locator('[aria-label="Notebook Entry Input"]')).toBeVisible();
|
await expect(page.locator('[aria-label="Notebook Entry Input"]')).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toHaveClass(/is-selected/);
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toHaveClass(/is-selected/);
|
||||||
});
|
});
|
||||||
test('When an object is dropped into a notebook, a new entry is created and it should be focused @unstable', async ({ page }) => {
|
test('When an object is dropped into a notebook, a new entry is created and it should be focused @unstable', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create Overlay Plot
|
// Create Overlay Plot
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Overlay Plot'
|
type: 'Overlay Plot'
|
||||||
@ -280,7 +296,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
// Reveal the notebook in the tree
|
// Reveal the notebook in the tree
|
||||||
await page.getByTitle('Show selected item in tree').click();
|
await page.getByTitle('Show selected item in tree').click();
|
||||||
|
|
||||||
await page.getByRole('treeitem', { name: overlayPlot.name }).dragTo(page.locator('.c-notebook__drag-area'));
|
await page
|
||||||
|
.getByRole('treeitem', { name: overlayPlot.name })
|
||||||
|
.dragTo(page.locator('.c-notebook__drag-area'));
|
||||||
|
|
||||||
const embed = page.locator('.c-ne__embed__link');
|
const embed = page.locator('.c-ne__embed__link');
|
||||||
const embedName = await embed.innerText();
|
const embedName = await embed.innerText();
|
||||||
@ -288,7 +306,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
await expect(embed).toHaveClass(/icon-plot-overlay/);
|
await expect(embed).toHaveClass(/icon-plot-overlay/);
|
||||||
expect(embedName).toBe(overlayPlot.name);
|
expect(embedName).toBe(overlayPlot.name);
|
||||||
});
|
});
|
||||||
test('When an object is dropped into a notebooks existing entry, it should be focused @unstable', async ({ page }) => {
|
test('When an object is dropped into a notebooks existing entry, it should be focused @unstable', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Create Overlay Plot
|
// Create Overlay Plot
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Overlay Plot'
|
type: 'Overlay Plot'
|
||||||
@ -301,7 +321,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
await page.getByTitle('Show selected item in tree').click();
|
await page.getByTitle('Show selected item in tree').click();
|
||||||
|
|
||||||
await nbUtils.enterTextEntry(page, 'Entry to drop into');
|
await nbUtils.enterTextEntry(page, 'Entry to drop into');
|
||||||
await page.getByRole('treeitem', { name: overlayPlot.name }).dragTo(page.locator('text=Entry to drop into'));
|
await page
|
||||||
|
.getByRole('treeitem', { name: overlayPlot.name })
|
||||||
|
.dragTo(page.locator('text=Entry to drop into'));
|
||||||
|
|
||||||
const existingEntry = page.locator('.c-ne__content', {
|
const existingEntry = page.locator('.c-ne__content', {
|
||||||
has: page.locator('text="Entry to drop into"')
|
has: page.locator('text="Entry to drop into"')
|
||||||
@ -332,7 +354,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
await expect(page.locator('text="Another First Entry"')).toBeVisible();
|
await expect(page.locator('text="Another First Entry"')).toBeVisible();
|
||||||
await expect(page.locator('text="Second Entry"')).toBeVisible();
|
await expect(page.locator('text="Second Entry"')).toBeVisible();
|
||||||
});
|
});
|
||||||
test('when a valid link is entered into a notebook entry, it becomes clickable when viewing', async ({ page }) => {
|
test('when a valid link is entered into a notebook entry, it becomes clickable when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const TEST_LINK = 'http://www.google.com';
|
const TEST_LINK = 'http://www.google.com';
|
||||||
|
|
||||||
// Navigate to the notebook object
|
// Navigate to the notebook object
|
||||||
@ -357,7 +381,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
|
|
||||||
expect(await validLink.count()).toBe(1);
|
expect(await validLink.count()).toBe(1);
|
||||||
});
|
});
|
||||||
test('when an invalid link is entered into a notebook entry, it does not become clickable when viewing', async ({ page }) => {
|
test('when an invalid link is entered into a notebook entry, it does not become clickable when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const TEST_LINK = 'www.google.com';
|
const TEST_LINK = 'www.google.com';
|
||||||
|
|
||||||
// Navigate to the notebook object
|
// Navigate to the notebook object
|
||||||
@ -372,7 +398,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
|
|
||||||
expect(await invalidLink.count()).toBe(0);
|
expect(await invalidLink.count()).toBe(0);
|
||||||
});
|
});
|
||||||
test('when a link is entered, but it is not in the whitelisted urls, it does not become clickable when viewing', async ({ page }) => {
|
test('when a link is entered, but it is not in the whitelisted urls, it does not become clickable when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const TEST_LINK = 'http://www.bing.com';
|
const TEST_LINK = 'http://www.bing.com';
|
||||||
|
|
||||||
// Navigate to the notebook object
|
// Navigate to the notebook object
|
||||||
@ -387,7 +415,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
|
|
||||||
expect(await invalidLink.count()).toBe(0);
|
expect(await invalidLink.count()).toBe(0);
|
||||||
});
|
});
|
||||||
test('when a valid link with a subdomain and a valid domain in the whitelisted urls is entered into a notebook entry, it becomes clickable when viewing', async ({ page }) => {
|
test('when a valid link with a subdomain and a valid domain in the whitelisted urls is entered into a notebook entry, it becomes clickable when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const INVALID_TEST_LINK = 'http://bing.google.com';
|
const INVALID_TEST_LINK = 'http://bing.google.com';
|
||||||
|
|
||||||
// Navigate to the notebook object
|
// Navigate to the notebook object
|
||||||
@ -402,7 +432,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
|
|
||||||
expect(await validLink.count()).toBe(1);
|
expect(await validLink.count()).toBe(1);
|
||||||
});
|
});
|
||||||
test('when a valid secure link is entered into a notebook entry, it becomes clickable when viewing', async ({ page }) => {
|
test('when a valid secure link is entered into a notebook entry, it becomes clickable when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const TEST_LINK = 'https://www.google.com';
|
const TEST_LINK = 'https://www.google.com';
|
||||||
|
|
||||||
// Navigate to the notebook object
|
// Navigate to the notebook object
|
||||||
@ -427,7 +459,9 @@ test.describe('Notebook entry tests', () => {
|
|||||||
|
|
||||||
expect(await validLink.count()).toBe(1);
|
expect(await validLink.count()).toBe(1);
|
||||||
});
|
});
|
||||||
test('when a nefarious link is entered into a notebook entry, it is sanitized when viewing', async ({ page }) => {
|
test('when a nefarious link is entered into a notebook entry, it is sanitized when viewing', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const TEST_LINK = 'http://www.google.com?bad=';
|
const TEST_LINK = 'http://www.google.com?bad=';
|
||||||
const TEST_LINK_BAD = `http://www.google.com?bad=<script>alert('gimme your cookies')</script>`;
|
const TEST_LINK_BAD = `http://www.google.com?bad=<script>alert('gimme your cookies')</script>`;
|
||||||
|
|
||||||
@ -437,7 +471,10 @@ test.describe('Notebook entry tests', () => {
|
|||||||
// Reveal the notebook in the tree
|
// Reveal the notebook in the tree
|
||||||
await page.getByTitle('Show selected item in tree').click();
|
await page.getByTitle('Show selected item in tree').click();
|
||||||
|
|
||||||
await nbUtils.enterTextEntry(page, `This should be a link, BUT not a bad link: ${TEST_LINK_BAD} is it?`);
|
await nbUtils.enterTextEntry(
|
||||||
|
page,
|
||||||
|
`This should be a link, BUT not a bad link: ${TEST_LINK_BAD} is it?`
|
||||||
|
);
|
||||||
|
|
||||||
const sanitizedLink = page.locator(`a[href="${TEST_LINK}"]`);
|
const sanitizedLink = page.locator(`a[href="${TEST_LINK}"]`);
|
||||||
const unsanitizedLink = page.locator(`a[href="${TEST_LINK_BAD}"]`);
|
const unsanitizedLink = page.locator(`a[href="${TEST_LINK_BAD}"]`);
|
||||||
|
@ -29,14 +29,19 @@ const { test, expect } = require('../../../../pluginFixtures');
|
|||||||
// const nbUtils = require('../../../../helper/notebookUtils');
|
// const nbUtils = require('../../../../helper/notebookUtils');
|
||||||
|
|
||||||
test.describe('Snapshot Menu tests', () => {
|
test.describe('Snapshot Menu tests', () => {
|
||||||
test.fixme('When no default notebook is selected, Snapshot Menu dropdown should only have a single option', async ({ page }) => {
|
test.fixme(
|
||||||
|
'When no default notebook is selected, Snapshot Menu dropdown should only have a single option',
|
||||||
|
async ({ page }) => {
|
||||||
// There should be no default notebook
|
// There should be no default notebook
|
||||||
// Clear default notebook if exists using `localStorage.setItem('notebook-storage', null);`
|
// Clear default notebook if exists using `localStorage.setItem('notebook-storage', null);`
|
||||||
// refresh page
|
// refresh page
|
||||||
// Click on 'Notebook Snaphot Menu'
|
// Click on 'Notebook Snaphot Menu'
|
||||||
// 'save to Notebook Snapshots' should be only option there
|
// 'save to Notebook Snapshots' should be only option there
|
||||||
});
|
}
|
||||||
test.fixme('When default notebook is updated selected, Snapshot Menu dropdown should list it as the newest option', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'When default notebook is updated selected, Snapshot Menu dropdown should list it as the newest option',
|
||||||
|
async ({ page }) => {
|
||||||
// Create 2a notebooks
|
// Create 2a notebooks
|
||||||
// Set Notebook A as Default
|
// Set Notebook A as Default
|
||||||
// Open Snapshot Menu and note that Notebook A is listed
|
// Open Snapshot Menu and note that Notebook A is listed
|
||||||
@ -44,7 +49,8 @@ test.describe('Snapshot Menu tests', () => {
|
|||||||
// Set Default Notebook to Notebook B
|
// Set Default Notebook to Notebook B
|
||||||
// Open Snapshot Notebook and note that Notebook B is listed
|
// Open Snapshot Notebook and note that Notebook B is listed
|
||||||
// Select Default Notebook Option and verify that Snapshot is added to Notebook B
|
// Select Default Notebook Option and verify that Snapshot is added to Notebook B
|
||||||
});
|
}
|
||||||
|
);
|
||||||
test.fixme('Can add Snapshots via Snapshot Menu and details are correct', async ({ page }) => {
|
test.fixme('Can add Snapshots via Snapshot Menu and details are correct', async ({ page }) => {
|
||||||
//Note this should be a visual test, too
|
//Note this should be a visual test, too
|
||||||
// Create Telemetry object
|
// Create Telemetry object
|
||||||
@ -82,12 +88,19 @@ test.describe('Snapshot Container tests', () => {
|
|||||||
await page.getByRole('button', { name: ' Snapshot ' }).click();
|
await page.getByRole('button', { name: ' Snapshot ' }).click();
|
||||||
await page.getByRole('menuitem', { name: ' Save to Notebook Snapshots' }).click();
|
await page.getByRole('menuitem', { name: ' Save to Notebook Snapshots' }).click();
|
||||||
await page.getByRole('button', { name: 'Show' }).click();
|
await page.getByRole('button', { name: 'Show' }).click();
|
||||||
|
|
||||||
});
|
});
|
||||||
test.fixme('5 Snapshots can be added to a container', async ({ page }) => {});
|
test.fixme('5 Snapshots can be added to a container', async ({ page }) => {});
|
||||||
test.fixme('5 Snapshots can be added to a container and Deleted with Delete All action', async ({ page }) => {});
|
test.fixme(
|
||||||
test.fixme('A snapshot can be Deleted from Container with 3 dot action menu', async ({ page }) => {});
|
'5 Snapshots can be added to a container and Deleted with Delete All action',
|
||||||
test.fixme('A snapshot can be Viewed, Annotated, display deleted, and saved from Container with 3 dot action menu', async ({ page }) => {
|
async ({ page }) => {}
|
||||||
|
);
|
||||||
|
test.fixme(
|
||||||
|
'A snapshot can be Deleted from Container with 3 dot action menu',
|
||||||
|
async ({ page }) => {}
|
||||||
|
);
|
||||||
|
test.fixme(
|
||||||
|
'A snapshot can be Viewed, Annotated, display deleted, and saved from Container with 3 dot action menu',
|
||||||
|
async ({ page }) => {
|
||||||
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
||||||
await page.getByRole('menuitem', { name: ' View Snapshot' }).click();
|
await page.getByRole('menuitem', { name: ' View Snapshot' }).click();
|
||||||
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
||||||
@ -98,16 +111,25 @@ test.describe('Snapshot Container tests', () => {
|
|||||||
await page.getByRole('button', { name: 'Save' }).click();
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
await page.getByRole('button', { name: 'Done' }).click();
|
await page.getByRole('button', { name: 'Done' }).click();
|
||||||
//await expect(await page.locator)
|
//await expect(await page.locator)
|
||||||
});
|
}
|
||||||
|
);
|
||||||
test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
|
test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
|
||||||
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
||||||
await page.getByRole('menuitem', { name: 'Quick View' }).click();
|
await page.getByRole('menuitem', { name: 'Quick View' }).click();
|
||||||
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
await expect(page.locator('.c-overlay__outer')).toBeVisible();
|
||||||
});
|
});
|
||||||
test.fixme('A snapshot can be Navigated To from Container with 3 dot action menu', async ({ page }) => {});
|
test.fixme(
|
||||||
test.fixme('A snapshot can be Navigated To Item in Time from Container with 3 dot action menu', async ({ page }) => {});
|
'A snapshot can be Navigated To from Container with 3 dot action menu',
|
||||||
|
async ({ page }) => {}
|
||||||
|
);
|
||||||
|
test.fixme(
|
||||||
|
'A snapshot can be Navigated To Item in Time from Container with 3 dot action menu',
|
||||||
|
async ({ page }) => {}
|
||||||
|
);
|
||||||
test.fixme('A snapshot Container can be open and closed', async ({ page }) => {});
|
test.fixme('A snapshot Container can be open and closed', async ({ page }) => {});
|
||||||
test.fixme('Can add object to Snapshot container and pull into notebook and create a new entry', async ({ page }) => {
|
test.fixme(
|
||||||
|
'Can add object to Snapshot container and pull into notebook and create a new entry',
|
||||||
|
async ({ page }) => {
|
||||||
//Create Notebook
|
//Create Notebook
|
||||||
//Create Telemetry Object
|
//Create Telemetry Object
|
||||||
//From Telemetry Object, use 'save to Notebook Snapshots'
|
//From Telemetry Object, use 'save to Notebook Snapshots'
|
||||||
@ -116,8 +138,11 @@ test.describe('Snapshot Container tests', () => {
|
|||||||
//Drag and Drop onto droppable area for new entry
|
//Drag and Drop onto droppable area for new entry
|
||||||
//New Entry created with given snapshot added
|
//New Entry created with given snapshot added
|
||||||
//Snapshot removed from container?
|
//Snapshot removed from container?
|
||||||
});
|
}
|
||||||
test.fixme('Can add object to Snapshot container and pull into notebook and existing entry', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'Can add object to Snapshot container and pull into notebook and existing entry',
|
||||||
|
async ({ page }) => {
|
||||||
//Create Notebook
|
//Create Notebook
|
||||||
//Create Telemetry Object
|
//Create Telemetry Object
|
||||||
//From Telemetry Object, use 'save to Notebook Snapshots'
|
//From Telemetry Object, use 'save to Notebook Snapshots'
|
||||||
@ -126,9 +151,13 @@ test.describe('Snapshot Container tests', () => {
|
|||||||
//Drag and Drop into exiting entry
|
//Drag and Drop into exiting entry
|
||||||
//Existing Entry updated with given snapshot
|
//Existing Entry updated with given snapshot
|
||||||
//Snapshot removed from container?
|
//Snapshot removed from container?
|
||||||
});
|
}
|
||||||
test.fixme('Verify Embedded options for PNG, JPG, and Annotate work correctly', async ({ page }) => {
|
);
|
||||||
|
test.fixme(
|
||||||
|
'Verify Embedded options for PNG, JPG, and Annotate work correctly',
|
||||||
|
async ({ page }) => {
|
||||||
//Add snapshot to container
|
//Add snapshot to container
|
||||||
//Verify PNG, JPG, and Annotate buttons work correctly
|
//Verify PNG, JPG, and Annotate buttons work correctly
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -36,8 +36,8 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
|||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
// Create Notebook
|
// Create Notebook
|
||||||
testNotebook = await createDomainObjectWithDefaults(page, {type: 'Notebook' });
|
testNotebook = await createDomainObjectWithDefaults(page, { type: 'Notebook' });
|
||||||
await page.goto(testNotebook.url, { waitUntil: 'networkidle'});
|
await page.goto(testNotebook.url, { waitUntil: 'networkidle' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Inspect Notebook Entry Network Requests', async ({ page }) => {
|
test('Inspect Notebook Entry Network Requests', async ({ page }) => {
|
||||||
@ -69,7 +69,9 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
|||||||
|
|
||||||
// Assert on request object
|
// Assert on request object
|
||||||
expect(notebookUrlRequest.postDataJSON().metadata.name).toBe(testNotebook.name);
|
expect(notebookUrlRequest.postDataJSON().metadata.name).toBe(testNotebook.name);
|
||||||
expect(notebookUrlRequest.postDataJSON().model.persisted).toBeGreaterThanOrEqual(notebookUrlRequest.postDataJSON().model.modified);
|
expect(notebookUrlRequest.postDataJSON().model.persisted).toBeGreaterThanOrEqual(
|
||||||
|
notebookUrlRequest.postDataJSON().model.modified
|
||||||
|
);
|
||||||
expect(allDocsRequest.postDataJSON().keys).toContain(testNotebook.uuid);
|
expect(allDocsRequest.postDataJSON().keys).toContain(testNotebook.uuid);
|
||||||
|
|
||||||
// Add an entry
|
// Add an entry
|
||||||
@ -186,9 +188,11 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
|||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
//Partial match for "Science" should only return Science
|
//Partial match for "Science" should only return Science
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]').first()).toContainText("Science");
|
await expect(page.locator('[aria-label="Search Result"]').first()).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Search Result"]').first()).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Search Result"]').first()).not.toContainText('Driving');
|
||||||
await expect(page.locator('[aria-label="Search Result"]').first()).not.toContainText("Drilling");
|
await expect(page.locator('[aria-label="Search Result"]').first()).not.toContainText(
|
||||||
|
'Drilling'
|
||||||
|
);
|
||||||
|
|
||||||
//Searching for a tag which does not exist should return an empty result
|
//Searching for a tag which does not exist should return an empty result
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
@ -200,8 +204,8 @@ test.describe('Notebook Tests with CouchDB @couchdb', () => {
|
|||||||
// Try to reduce indeterminism of browser requests by only returning fetch requests.
|
// Try to reduce indeterminism of browser requests by only returning fetch requests.
|
||||||
// Filter out preflight CORS, fetching stylesheets, page icons, etc. that can occur during tests
|
// Filter out preflight CORS, fetching stylesheets, page icons, etc. that can occur during tests
|
||||||
function filterNonFetchRequests(requests) {
|
function filterNonFetchRequests(requests) {
|
||||||
return requests.filter(request => {
|
return requests.filter((request) => {
|
||||||
return (request.resourceType() === 'fetch');
|
return request.resourceType() === 'fetch';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +240,9 @@ async function removeTagAndAwaitNetwork(page, tagName) {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.locator(`[aria-label="Remove tag ${tagName}"]`).click(),
|
page.locator(`[aria-label="Remove tag ${tagName}"]`).click(),
|
||||||
//With this pattern, we're awaiting the response but asserting on the request payload.
|
//With this pattern, we're awaiting the response but asserting on the request payload.
|
||||||
page.waitForResponse(resp => resp.request().postData().includes(`"_deleted":true`) && resp.status() === 201)
|
page.waitForResponse(
|
||||||
|
(resp) => resp.request().postData().includes(`"_deleted":true`) && resp.status() === 201
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
await expect(page.locator(`[aria-label="Tag"]:has-text("${tagName}")`)).toBeHidden();
|
await expect(page.locator(`[aria-label="Tag"]:has-text("${tagName}")`)).toBeHidden();
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
|
@ -21,7 +21,10 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/* global __dirname */
|
/* global __dirname */
|
||||||
const { test, expect, streamToString } = require('../../../../pluginFixtures');
|
const { test, expect, streamToString } = require('../../../../pluginFixtures');
|
||||||
const { openObjectTreeContextMenu, createDomainObjectWithDefaults } = require('../../../../appActions');
|
const {
|
||||||
|
openObjectTreeContextMenu,
|
||||||
|
createDomainObjectWithDefaults
|
||||||
|
} = require('../../../../appActions');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const nbUtils = require('../../../../helper/notebookUtils');
|
const nbUtils = require('../../../../helper/notebookUtils');
|
||||||
|
|
||||||
@ -65,13 +68,11 @@ test.describe('Restricted Notebook', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can be locked if at least one page has one entry @addInit', async ({ page }) => {
|
test('Can be locked if at least one page has one entry @addInit', async ({ page }) => {
|
||||||
|
|
||||||
await nbUtils.enterTextEntry(page, TEST_TEXT);
|
await nbUtils.enterTextEntry(page, TEST_TEXT);
|
||||||
|
|
||||||
const commitButton = page.locator('button:has-text("Commit Entries")');
|
const commitButton = page.locator('button:has-text("Commit Entries")');
|
||||||
expect(await commitButton.count()).toEqual(1);
|
expect(await commitButton.count()).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Restricted Notebook with at least one entry and with the page locked @addInit', () => {
|
test.describe('Restricted Notebook with at least one entry and with the page locked @addInit', () => {
|
||||||
@ -85,11 +86,15 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
|||||||
await page.locator('button.c-notebook__toggle-nav-button').click();
|
await page.locator('button.c-notebook__toggle-nav-button').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Locked page should now be in a locked state @addInit @unstable', async ({ page }, testInfo) => {
|
test('Locked page should now be in a locked state @addInit @unstable', async ({
|
||||||
|
page
|
||||||
|
}, testInfo) => {
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(testInfo.project === 'chrome-beta', "Test is unreliable on chrome-beta");
|
test.skip(testInfo.project === 'chrome-beta', 'Test is unreliable on chrome-beta');
|
||||||
// main lock message on page
|
// main lock message on page
|
||||||
const lockMessage = page.locator('text=This page has been committed and cannot be modified or removed');
|
const lockMessage = page.locator(
|
||||||
|
'text=This page has been committed and cannot be modified or removed'
|
||||||
|
);
|
||||||
expect.soft(await lockMessage.count()).toEqual(1);
|
expect.soft(await lockMessage.count()).toEqual(1);
|
||||||
|
|
||||||
// lock icon on page in sidebar
|
// lock icon on page in sidebar
|
||||||
@ -103,7 +108,9 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
|||||||
await expect(menuOptions).not.toContainText('Remove');
|
await expect(menuOptions).not.toContainText('Remove');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can still: add page, rename, add entry, delete unlocked pages @addInit', async ({ page }) => {
|
test('Can still: add page, rename, add entry, delete unlocked pages @addInit', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Add a new page to the section
|
// Add a new page to the section
|
||||||
await page.getByRole('button', { name: 'Add Page' }).click();
|
await page.getByRole('button', { name: 'Add Page' }).click();
|
||||||
// Focus the new page by clicking it
|
// Focus the new page by clicking it
|
||||||
@ -138,7 +145,6 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Restricted Notebook with a page locked and with an embed @addInit', () => {
|
test.describe('Restricted Notebook with a page locked and with an embed @addInit', () => {
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
const notebook = await startAndAddRestrictedNotebookObject(page);
|
const notebook = await startAndAddRestrictedNotebookObject(page);
|
||||||
await nbUtils.dragAndDropEmbed(page, notebook);
|
await nbUtils.dragAndDropEmbed(page, notebook);
|
||||||
@ -160,7 +166,6 @@ test.describe('Restricted Notebook with a page locked and with an embed @addInit
|
|||||||
const embedMenu = page.locator('body >> .c-menu');
|
const embedMenu = page.locator('body >> .c-menu');
|
||||||
await expect(embedMenu).not.toContainText('Remove This Embed');
|
await expect(embedMenu).not.toContainText('Remove This Embed');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('can export restricted notebook as text', () => {
|
test.describe('can export restricted notebook as text', () => {
|
||||||
@ -181,7 +186,6 @@ test.describe('can export restricted notebook as text', () => {
|
|||||||
const readStream = await download.createReadStream();
|
const readStream = await download.createReadStream();
|
||||||
const exportedText = await streamToString(readStream);
|
const exportedText = await streamToString(readStream);
|
||||||
expect(exportedText).toContain('Foo bar entry');
|
expect(exportedText).toContain('Foo bar entry');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme('can export multiple notebook entries as text ', async ({ page }) => {});
|
test.fixme('can export multiple notebook entries as text ', async ({ page }) => {});
|
||||||
@ -194,7 +198,9 @@ test.describe('can export restricted notebook as text', () => {
|
|||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
*/
|
*/
|
||||||
async function startAndAddRestrictedNotebookObject(page) {
|
async function startAndAddRestrictedNotebookObject(page) {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../../../helper/', 'addInitRestrictedNotebook.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../../../helper/', 'addInitRestrictedNotebook.js')
|
||||||
|
});
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
return createDomainObjectWithDefaults(page, { type: CUSTOM_NAME });
|
return createDomainObjectWithDefaults(page, { type: CUSTOM_NAME });
|
||||||
|
@ -91,22 +91,22 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
|
|
||||||
await page.locator('[placeholder="Type to select tag"]').click();
|
await page.locator('[placeholder="Type to select tag"]').click();
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText('Drilling');
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Driving");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText('Driving');
|
||||||
});
|
});
|
||||||
test('Can add tags', async ({ page }) => {
|
test('Can add tags', async ({ page }) => {
|
||||||
await createNotebookEntryAndTags(page);
|
await createNotebookEntryAndTags(page);
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Driving");
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText('Driving');
|
||||||
|
|
||||||
await page.locator('button:has-text("Add Tag")').click();
|
await page.locator('button:has-text("Add Tag")').click();
|
||||||
await page.locator('[placeholder="Type to select tag"]').click();
|
await page.locator('[placeholder="Type to select tag"]').click();
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText("Science");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).not.toContainText('Driving');
|
||||||
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText("Drilling");
|
await expect(page.locator('[aria-label="Autocomplete Options"]')).toContainText('Drilling');
|
||||||
});
|
});
|
||||||
test('Can add tags with blank entry', async ({ page }) => {
|
test('Can add tags with blank entry', async ({ page }) => {
|
||||||
await createDomainObjectWithDefaults(page, { type: 'Notebook' });
|
await createDomainObjectWithDefaults(page, { type: 'Notebook' });
|
||||||
@ -121,7 +121,7 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
// Select the "Driving" tag
|
// Select the "Driving" tag
|
||||||
await page.locator('[aria-label="Autocomplete Options"] >> text=Driving').click();
|
await page.locator('[aria-label="Autocomplete Options"] >> text=Driving').click();
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText("Driving");
|
await expect(page.locator('[aria-label="Notebook Entry"]')).toContainText('Driving');
|
||||||
});
|
});
|
||||||
test('Can cancel adding tags', async ({ page }) => {
|
test('Can cancel adding tags', async ({ page }) => {
|
||||||
await createNotebookAndEntry(page);
|
await createNotebookAndEntry(page);
|
||||||
@ -148,13 +148,13 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
await createNotebookEntryAndTags(page);
|
await createNotebookEntryAndTags(page);
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Search Result"]')).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText('Driving');
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Search Result"]')).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText('Driving');
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Xq');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Xq');
|
||||||
@ -169,7 +169,7 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Search Result"]')).toContainText('Science');
|
||||||
await page.getByText('Entry 0').click();
|
await page.getByText('Entry 0').click();
|
||||||
await expect(page.locator('.js-preview-window')).toBeVisible();
|
await expect(page.locator('.js-preview-window')).toBeVisible();
|
||||||
});
|
});
|
||||||
@ -180,11 +180,11 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
await page.hover('[aria-label="Tag"]:has-text("Driving")');
|
await page.hover('[aria-label="Tag"]:has-text("Driving")');
|
||||||
await page.locator('[aria-label="Remove tag Driving"]').click();
|
await page.locator('[aria-label="Remove tag Driving"]').click();
|
||||||
|
|
||||||
await expect(page.locator('[aria-label="Tags Inspector"]')).toContainText("Science");
|
await expect(page.locator('[aria-label="Tags Inspector"]')).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Tags Inspector"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Tags Inspector"]')).not.toContainText('Driving');
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText("Driving");
|
await expect(page.locator('[aria-label="Search Result"]')).not.toContainText('Driving');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can delete entries without tags', async ({ page }) => {
|
test('Can delete entries without tags', async ({ page }) => {
|
||||||
@ -203,9 +203,13 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
|
|
||||||
await page.hover('[aria-label="Notebook Entry Input"] >> nth=1');
|
await page.hover('[aria-label="Notebook Entry Input"] >> nth=1');
|
||||||
await page.locator('button[title="Delete this entry"]').last().click();
|
await page.locator('button[title="Delete this entry"]').last().click();
|
||||||
await expect(page.locator('text=This action will permanently delete this entry. Do you wish to continue?')).toBeVisible();
|
await expect(
|
||||||
|
page.locator('text=This action will permanently delete this entry. Do you wish to continue?')
|
||||||
|
).toBeVisible();
|
||||||
await page.locator('button:has-text("Ok")').click();
|
await page.locator('button:has-text("Ok")').click();
|
||||||
await expect(page.locator('text=This action will permanently delete this entry. Do you wish to continue?')).toBeHidden();
|
await expect(
|
||||||
|
page.locator('text=This action will permanently delete this entry. Do you wish to continue?')
|
||||||
|
).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can delete objects with tags and neither return in search', async ({ page }) => {
|
test('Can delete objects with tags and neither return in search', async ({ page }) => {
|
||||||
@ -234,8 +238,8 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
// Verify tags are present
|
// Verify tags are present
|
||||||
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
||||||
await expect(page.locator(entryLocator)).toContainText("Science");
|
await expect(page.locator(entryLocator)).toContainText('Science');
|
||||||
await expect(page.locator(entryLocator)).toContainText("Driving");
|
await expect(page.locator(entryLocator)).toContainText('Driving');
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reload Page
|
//Reload Page
|
||||||
@ -244,8 +248,8 @@ test.describe('Tagging in Notebooks @addInit', () => {
|
|||||||
// Verify tags persist across reload
|
// Verify tags persist across reload
|
||||||
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
for (let iteration = 0; iteration < ITERATIONS; iteration++) {
|
||||||
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
const entryLocator = `[aria-label="Notebook Entry"] >> nth = ${iteration}`;
|
||||||
await expect(page.locator(entryLocator)).toContainText("Science");
|
await expect(page.locator(entryLocator)).toContainText('Science');
|
||||||
await expect(page.locator(entryLocator)).toContainText("Driving");
|
await expect(page.locator(entryLocator)).toContainText('Driving');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
test('Can cancel adding a tag', async ({ page }) => {
|
test('Can cancel adding a tag', async ({ page }) => {
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/* global __dirname */
|
/* global __dirname */
|
||||||
/*
|
/*
|
||||||
* This test suite is dedicated to testing the operator status plugin.
|
* This test suite is dedicated to testing the operator status plugin.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
@ -40,8 +40,12 @@ STUB (test.fixme) Rolling through each
|
|||||||
test.describe('Operator Status', () => {
|
test.describe('Operator Status', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// FIXME: determine if plugins will be added to index.html or need to be injected
|
// FIXME: determine if plugins will be added to index.html or need to be injected
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../../../helper/', 'addInitExampleUser.js')});
|
await page.addInitScript({
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../../../helper/', 'addInitOperatorStatus.js')});
|
path: path.join(__dirname, '../../../../helper/', 'addInitExampleUser.js')
|
||||||
|
});
|
||||||
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../../../helper/', 'addInitOperatorStatus.js')
|
||||||
|
});
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,7 +80,7 @@ test.describe('Operator Status', () => {
|
|||||||
|
|
||||||
// get selected status value
|
// get selected status value
|
||||||
const selectStatus = page.locator('select[name="setStatus"]');
|
const selectStatus = page.locator('select[name="setStatus"]');
|
||||||
await selectStatus.selectOption({ index: 1});
|
await selectStatus.selectOption({ index: 1 });
|
||||||
const initialStatusValue = await selectStatus.inputValue();
|
const initialStatusValue = await selectStatus.inputValue();
|
||||||
|
|
||||||
// open manage status poll
|
// open manage status poll
|
||||||
@ -88,13 +92,14 @@ test.describe('Operator Status', () => {
|
|||||||
const rowValuesArr = rowValues.split('\t');
|
const rowValuesArr = rowValues.split('\t');
|
||||||
const COLUMN_STATUS_INDEX = 1;
|
const COLUMN_STATUS_INDEX = 1;
|
||||||
// check initial set value matches status table
|
// check initial set value matches status table
|
||||||
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase())
|
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
|
||||||
.toEqual(initialStatusValue.toLowerCase());
|
initialStatusValue.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
// change user status
|
// change user status
|
||||||
await statusPollIndicator.click();
|
await statusPollIndicator.click();
|
||||||
// FIXME: might want to grab a dynamic option instead of arbitrary
|
// FIXME: might want to grab a dynamic option instead of arbitrary
|
||||||
await page.locator('select[name="setStatus"]').selectOption({ index: 2});
|
await page.locator('select[name="setStatus"]').selectOption({ index: 2 });
|
||||||
const updatedStatusValue = await selectStatus.inputValue();
|
const updatedStatusValue = await selectStatus.inputValue();
|
||||||
// verify user status is reflected in table
|
// verify user status is reflected in table
|
||||||
await manageStatusPollIndicator.click();
|
await manageStatusPollIndicator.click();
|
||||||
@ -103,9 +108,9 @@ test.describe('Operator Status', () => {
|
|||||||
const updatedRowValues = await updatedRow.innerText();
|
const updatedRowValues = await updatedRow.innerText();
|
||||||
const updatedRowValuesArr = updatedRowValues.split('\t');
|
const updatedRowValuesArr = updatedRowValues.split('\t');
|
||||||
|
|
||||||
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX].toLowerCase())
|
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
|
||||||
.toEqual(updatedStatusValue.toLowerCase());
|
updatedStatusValue.toLowerCase()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('clear poll button removes poll responses', async ({ page }) => {
|
test('clear poll button removes poll responses', async ({ page }) => {
|
||||||
@ -120,7 +125,7 @@ test.describe('Operator Status', () => {
|
|||||||
// get selected status value
|
// get selected status value
|
||||||
const selectStatus = page.locator('select[name="setStatus"]');
|
const selectStatus = page.locator('select[name="setStatus"]');
|
||||||
// FIXME: might want to grab a dynamic option instead of arbitrary
|
// FIXME: might want to grab a dynamic option instead of arbitrary
|
||||||
await selectStatus.selectOption({ index: 1});
|
await selectStatus.selectOption({ index: 1 });
|
||||||
const initialStatusValue = await selectStatus.inputValue();
|
const initialStatusValue = await selectStatus.inputValue();
|
||||||
|
|
||||||
// open manage status poll
|
// open manage status poll
|
||||||
@ -132,8 +137,9 @@ test.describe('Operator Status', () => {
|
|||||||
const rowValuesArr = rowValues.split('\t');
|
const rowValuesArr = rowValues.split('\t');
|
||||||
const COLUMN_STATUS_INDEX = 1;
|
const COLUMN_STATUS_INDEX = 1;
|
||||||
// check initial set value matches status table
|
// check initial set value matches status table
|
||||||
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase())
|
expect(rowValuesArr[COLUMN_STATUS_INDEX].toLowerCase()).toEqual(
|
||||||
.toEqual(initialStatusValue.toLowerCase());
|
initialStatusValue.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
// clear the poll
|
// clear the poll
|
||||||
await page.locator('button[title="Clear the previous poll question"]').click();
|
await page.locator('button[title="Clear the previous poll question"]').click();
|
||||||
@ -142,13 +148,10 @@ test.describe('Operator Status', () => {
|
|||||||
const updatedRowValues = await updatedRow.innerText();
|
const updatedRowValues = await updatedRow.innerText();
|
||||||
const updatedRowValuesArr = updatedRowValues.split('\t');
|
const updatedRowValuesArr = updatedRowValues.split('\t');
|
||||||
const UNSET_VALUE_LABEL = 'Not set';
|
const UNSET_VALUE_LABEL = 'Not set';
|
||||||
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX])
|
expect(updatedRowValuesArr[COLUMN_STATUS_INDEX]).toEqual(UNSET_VALUE_LABEL);
|
||||||
.toEqual(UNSET_VALUE_LABEL);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme('iterate through all possible response values', async ({ page }) => {
|
test.fixme('iterate through all possible response values', async ({ page }) => {
|
||||||
// test all possible respone values for the poll
|
// test all possible respone values for the poll
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -65,17 +65,29 @@ test.describe('Autoscale', () => {
|
|||||||
]);
|
]);
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
|
|
||||||
// Make sure that after turning off autoscale, the user entered range values are reflexted in the ticks.
|
// Make sure that after turning off autoscale, the user entered range values are reflexted in the ticks.
|
||||||
await testYTicks(page, ['-2.00', '-1.50', '-1.00', '-0.50', '0.00', '0.50', '1.00', '1.50', '2.00']);
|
await testYTicks(page, [
|
||||||
|
'-2.00',
|
||||||
|
'-1.50',
|
||||||
|
'-1.00',
|
||||||
|
'-0.50',
|
||||||
|
'0.00',
|
||||||
|
'0.50',
|
||||||
|
'1.00',
|
||||||
|
'1.50',
|
||||||
|
'2.00'
|
||||||
|
]);
|
||||||
|
|
||||||
const canvas = page.locator('canvas').nth(1);
|
const canvas = page.locator('canvas').nth(1);
|
||||||
|
|
||||||
await canvas.hover({trial: true});
|
await canvas.hover({ trial: true });
|
||||||
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
|
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
|
||||||
|
|
||||||
expect.soft(await canvas.screenshot()).toMatchSnapshot('autoscale-canvas-prepan.png', { animations: 'disabled' });
|
expect
|
||||||
|
.soft(await canvas.screenshot())
|
||||||
|
.toMatchSnapshot('autoscale-canvas-prepan.png', { animations: 'disabled' });
|
||||||
|
|
||||||
//Alt Drag Start
|
//Alt Drag Start
|
||||||
await page.keyboard.down('Alt');
|
await page.keyboard.down('Alt');
|
||||||
@ -98,9 +110,11 @@ test.describe('Autoscale', () => {
|
|||||||
await testYTicks(page, ['0.00', '0.50', '1.00', '1.50', '2.00', '2.50', '3.00', '3.50']);
|
await testYTicks(page, ['0.00', '0.50', '1.00', '1.50', '2.00', '2.50', '3.00', '3.50']);
|
||||||
|
|
||||||
//Wait for canvas to stablize.
|
//Wait for canvas to stablize.
|
||||||
await canvas.hover({trial: true});
|
await canvas.hover({ trial: true });
|
||||||
|
|
||||||
expect.soft(await canvas.screenshot()).toMatchSnapshot('autoscale-canvas-panned.png', { animations: 'disabled' });
|
expect
|
||||||
|
.soft(await canvas.screenshot())
|
||||||
|
.toMatchSnapshot('autoscale-canvas-panned.png', { animations: 'disabled' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,7 +123,11 @@ test.describe('Autoscale', () => {
|
|||||||
* @param {string} start
|
* @param {string} start
|
||||||
* @param {string} end
|
* @param {string} end
|
||||||
*/
|
*/
|
||||||
async function setTimeRange(page, start = '2022-03-29 22:00:00.000Z', end = '2022-03-29 22:00:30.000Z') {
|
async function setTimeRange(
|
||||||
|
page,
|
||||||
|
start = '2022-03-29 22:00:00.000Z',
|
||||||
|
end = '2022-03-29 22:00:30.000Z'
|
||||||
|
) {
|
||||||
// Set a specific time range for consistency, otherwise it will change
|
// Set a specific time range for consistency, otherwise it will change
|
||||||
// on every test to a range based on the current time.
|
// on every test to a range based on the current time.
|
||||||
|
|
||||||
@ -139,10 +157,13 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
|
|||||||
]);
|
]);
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
|
|
||||||
// save (exit edit mode)
|
// save (exit edit mode)
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
await page.locator('text=Save and Finish Editing').click();
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
|
|
||||||
// click create button
|
// click create button
|
||||||
@ -158,7 +179,7 @@ async function createSinewaveOverlayPlot(page, myItemsFolderName) {
|
|||||||
]);
|
]);
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
|
|
||||||
// focus the overlay plot
|
// focus the overlay plot
|
||||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||||
@ -194,7 +215,7 @@ async function setUserDefinedMinAndMax(page, min, max) {
|
|||||||
async function testYTicks(page, values) {
|
async function testYTicks(page, values) {
|
||||||
const yTicks = page.locator('.gl-plot-y-tick-label');
|
const yTicks = page.locator('.gl-plot-y-tick-label');
|
||||||
await page.locator('canvas >> nth=1').hover();
|
await page.locator('canvas >> nth=1').hover();
|
||||||
let promises = [yTicks.count().then(c => expect(c).toBe(values.length))];
|
let promises = [yTicks.count().then((c) => expect(c).toBe(values.length))];
|
||||||
|
|
||||||
for (let i = 0, l = values.length; i < l; i += 1) {
|
for (let i = 0, l = values.length; i < l; i += 1) {
|
||||||
promises.push(expect.soft(yTicks.nth(i)).toHaveText(values[i])); // eslint-disable-line
|
promises.push(expect.soft(yTicks.nth(i)).toHaveText(values[i])); // eslint-disable-line
|
||||||
|
@ -29,7 +29,10 @@ const { test, expect } = require('../../../../pluginFixtures');
|
|||||||
const { selectInspectorTab } = require('../../../../appActions');
|
const { selectInspectorTab } = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Log plot tests', () => {
|
test.describe('Log plot tests', () => {
|
||||||
test('Log Plot ticks are functionally correct in regular and log mode and after refresh', async ({ page, openmctConfig }) => {
|
test('Log Plot ticks are functionally correct in regular and log mode and after refresh', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
//Test.slow decorator is currently broken. Needs to be fixed in https://github.com/nasa/openmct/issues/5374
|
//Test.slow decorator is currently broken. Needs to be fixed in https://github.com/nasa/openmct/issues/5374
|
||||||
@ -51,7 +54,9 @@ test.describe('Log plot tests', () => {
|
|||||||
|
|
||||||
// Leaving test as 'TODO' for now.
|
// Leaving test as 'TODO' for now.
|
||||||
// NOTE: Not eligible for community contributions.
|
// NOTE: Not eligible for community contributions.
|
||||||
test.fixme('Verify that log mode option is reflected in import/export JSON', async ({ page, openmctConfig }) => {
|
test.fixme(
|
||||||
|
'Verify that log mode option is reflected in import/export JSON',
|
||||||
|
async ({ page, openmctConfig }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
await makeOverlayPlot(page, myItemsFolderName);
|
await makeOverlayPlot(page, myItemsFolderName);
|
||||||
@ -66,7 +71,8 @@ test.describe('Log plot tests', () => {
|
|||||||
// TODO, the plot is slightly at different position that in the other test, so this fails.
|
// TODO, the plot is slightly at different position that in the other test, so this fails.
|
||||||
// ...We can fix it by copying all steps from the first test...
|
// ...We can fix it by copying all steps from the first test...
|
||||||
// await testLogPlotPixels(page);
|
// await testLogPlotPixels(page);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,14 +99,14 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
|||||||
await page.locator('button.c-create-button').click();
|
await page.locator('button.c-create-button').click();
|
||||||
await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
|
await page.locator('li[role="menuitem"]:has-text("Overlay Plot")').click();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.locator('button:has-text("OK")').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
|
|
||||||
// save the overlay plot
|
// save the overlay plot
|
||||||
|
|
||||||
@ -125,14 +131,14 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
|||||||
// Click OK to make generator
|
// Click OK to make generator
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.locator('button:has-text("OK")').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
]);
|
]);
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
|
|
||||||
// click on overlay plot
|
// click on overlay plot
|
||||||
|
|
||||||
@ -205,7 +211,10 @@ async function disableLogMode(page) {
|
|||||||
*/
|
*/
|
||||||
async function saveOverlayPlot(page) {
|
async function saveOverlayPlot(page) {
|
||||||
// save overlay plot
|
// save overlay plot
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.locator('text=Save and Finish Editing').click(),
|
page.locator('text=Save and Finish Editing').click(),
|
||||||
|
@ -27,14 +27,18 @@ Tests to verify log plot functionality when objects are missing
|
|||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
|
|
||||||
test.describe('Handle missing object for plots', () => {
|
test.describe('Handle missing object for plots', () => {
|
||||||
test('Displays empty div for missing stacked plot item @unstable', async ({ page, browserName, openmctConfig }) => {
|
test('Displays empty div for missing stacked plot item @unstable', async ({
|
||||||
|
page,
|
||||||
|
browserName,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(browserName === 'firefox', 'Firefox failing due to console events being missed');
|
test.skip(browserName === 'firefox', 'Firefox failing due to console events being missed');
|
||||||
|
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
const errorLogs = [];
|
const errorLogs = [];
|
||||||
|
|
||||||
page.on("console", (message) => {
|
page.on('console', (message) => {
|
||||||
if (message.type() === 'warning' && message.text().includes('Missing domain object')) {
|
if (message.type() === 'warning' && message.text().includes('Missing domain object')) {
|
||||||
errorLogs.push(message.text());
|
errorLogs.push(message.text());
|
||||||
}
|
}
|
||||||
@ -52,18 +56,15 @@ test.describe('Handle missing object for plots', () => {
|
|||||||
delete parsedData[lastKey];
|
delete parsedData[lastKey];
|
||||||
|
|
||||||
//Sets local storage with missing object
|
//Sets local storage with missing object
|
||||||
await page.evaluate(
|
await page.evaluate(`window.localStorage.setItem('mct', '${JSON.stringify(parsedData)}')`);
|
||||||
`window.localStorage.setItem('mct', '${JSON.stringify(parsedData)}')`
|
|
||||||
);
|
|
||||||
|
|
||||||
//Reloads page and clicks on stacked plot
|
//Reloads page and clicks on stacked plot
|
||||||
await Promise.all([
|
await Promise.all([page.reload(), page.waitForLoadState('networkidle')]);
|
||||||
page.reload(),
|
|
||||||
page.waitForLoadState('networkidle')
|
|
||||||
]);
|
|
||||||
|
|
||||||
//Verify Main section is there on load
|
//Verify Main section is there on load
|
||||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Stacked Plot');
|
await expect
|
||||||
|
.soft(page.locator('.l-browse-bar__object-name'))
|
||||||
|
.toContainText('Unnamed Stacked Plot');
|
||||||
|
|
||||||
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
await page.locator(`text=Open MCT ${myItemsFolderName} >> span`).nth(3).click();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -72,7 +73,7 @@ test.describe('Handle missing object for plots', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
//Check that there is only one stacked item plot with a plot, the missing one will be empty
|
//Check that there is only one stacked item plot with a plot, the missing one will be empty
|
||||||
await expect(page.locator(".c-plot--stacked-container:has(.gl-plot)")).toHaveCount(1);
|
await expect(page.locator('.c-plot--stacked-container:has(.gl-plot)')).toHaveCount(1);
|
||||||
//Verify that console.warn is thrown
|
//Verify that console.warn is thrown
|
||||||
expect(errorLogs).toHaveLength(1);
|
expect(errorLogs).toHaveLength(1);
|
||||||
});
|
});
|
||||||
@ -91,7 +92,7 @@ async function makeStackedPlot(page, myItemsFolderName) {
|
|||||||
await page.locator('li[role="menuitem"]:has-text("Stacked Plot")').click();
|
await page.locator('li[role="menuitem"]:has-text("Stacked Plot")').click();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.locator('button:has-text("OK")').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
@ -127,7 +128,10 @@ async function makeStackedPlot(page, myItemsFolderName) {
|
|||||||
*/
|
*/
|
||||||
async function saveStackedPlot(page) {
|
async function saveStackedPlot(page) {
|
||||||
// save stacked plot
|
// save stacked plot
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.locator('text=Save and Finish Editing').click(),
|
page.locator('text=Save and Finish Editing').click(),
|
||||||
@ -149,7 +153,7 @@ async function createSineWaveGenerator(page) {
|
|||||||
await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
|
await page.locator('li[role="menuitem"]:has-text("Sine Wave Generator")').click();
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation({ waitUntil: 'networkidle'}),
|
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||||
page.locator('button:has-text("OK")').click(),
|
page.locator('button:has-text("OK")').click(),
|
||||||
//Wait for Save Banner to appear
|
//Wait for Save Banner to appear
|
||||||
page.waitForSelector('.c-message-banner__message')
|
page.waitForSelector('.c-message-banner__message')
|
||||||
|
@ -26,7 +26,12 @@ necessarily be used for reference when writing new tests in this area.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, getCanvasPixels, selectInspectorTab, waitForPlotsToRender } = require('../../../../appActions');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
getCanvasPixels,
|
||||||
|
selectInspectorTab,
|
||||||
|
waitForPlotsToRender
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Overlay Plot', () => {
|
test.describe('Overlay Plot', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
@ -35,11 +40,11 @@ test.describe('Overlay Plot', () => {
|
|||||||
|
|
||||||
test('Plot legend color is in sync with plot series color', async ({ page }) => {
|
test('Plot legend color is in sync with plot series color', async ({ page }) => {
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Overlay Plot"
|
type: 'Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -53,22 +58,26 @@ test.describe('Overlay Plot', () => {
|
|||||||
await page.locator('.c-click-swatch--menu').click();
|
await page.locator('.c-click-swatch--menu').click();
|
||||||
await page.locator('.c-palette__item[style="background: rgb(255, 166, 61);"]').click();
|
await page.locator('.c-palette__item[style="background: rgb(255, 166, 61);"]').click();
|
||||||
// gets color for swatch located in legend
|
// gets color for swatch located in legend
|
||||||
const seriesColorSwatch = page.locator('.gl-plot-y-label-swatch-container > .plot-series-color-swatch');
|
const seriesColorSwatch = page.locator(
|
||||||
|
'.gl-plot-y-label-swatch-container > .plot-series-color-swatch'
|
||||||
|
);
|
||||||
await expect(seriesColorSwatch).toHaveCSS('background-color', 'rgb(255, 166, 61)');
|
await expect(seriesColorSwatch).toHaveCSS('background-color', 'rgb(255, 166, 61)');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Limit lines persist when series is moved to another Y Axis and on refresh', async ({ page }) => {
|
test('Limit lines persist when series is moved to another Y Axis and on refresh', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/6338'
|
description: 'https://github.com/nasa/openmct/issues/6338'
|
||||||
});
|
});
|
||||||
// Create an Overlay Plot with a default SWG
|
// Create an Overlay Plot with a default SWG
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Overlay Plot"
|
type: 'Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
const swgA = await createDomainObjectWithDefaults(page, {
|
const swgA = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -83,8 +92,15 @@ test.describe('Overlay Plot', () => {
|
|||||||
|
|
||||||
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
||||||
await selectInspectorTab(page, 'Config');
|
await selectInspectorTab(page, 'Config');
|
||||||
await page.getByRole('list', { name: 'Plot Series Properties' }).locator('span').first().click();
|
await page
|
||||||
await page.getByRole('list', { name: 'Plot Series Properties' }).locator('[title="Display limit lines"]~div input').check();
|
.getByRole('list', { name: 'Plot Series Properties' })
|
||||||
|
.locator('span')
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
await page
|
||||||
|
.getByRole('list', { name: 'Plot Series Properties' })
|
||||||
|
.locator('[title="Display limit lines"]~div input')
|
||||||
|
.check();
|
||||||
|
|
||||||
await assertLimitLinesExistAndAreVisible(page);
|
await assertLimitLinesExistAndAreVisible(page);
|
||||||
|
|
||||||
@ -104,7 +120,9 @@ test.describe('Overlay Plot', () => {
|
|||||||
await selectInspectorTab(page, 'Elements');
|
await selectInspectorTab(page, 'Elements');
|
||||||
|
|
||||||
// Drag Sine Wave Generator series from Y Axis 1 into Y Axis 2
|
// Drag Sine Wave Generator series from Y Axis 1 into Y Axis 2
|
||||||
await page.locator(`#inspector-elements-tree >> text=${swgA.name}`).dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
await page
|
||||||
|
.locator(`#inspector-elements-tree >> text=${swgA.name}`)
|
||||||
|
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
||||||
|
|
||||||
await assertLimitLinesExistAndAreVisible(page);
|
await assertLimitLinesExistAndAreVisible(page);
|
||||||
|
|
||||||
@ -117,32 +135,33 @@ test.describe('Overlay Plot', () => {
|
|||||||
await page.reload();
|
await page.reload();
|
||||||
|
|
||||||
await assertLimitLinesExistAndAreVisible(page);
|
await assertLimitLinesExistAndAreVisible(page);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('The elements pool supports dragging series into multiple y-axis buckets', async ({ page }) => {
|
test('The elements pool supports dragging series into multiple y-axis buckets', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Overlay Plot"
|
type: 'Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
const swgA = await createDomainObjectWithDefaults(page, {
|
const swgA = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
const swgB = await createDomainObjectWithDefaults(page, {
|
const swgB = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
const swgC = await createDomainObjectWithDefaults(page, {
|
const swgC = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
const swgD = await createDomainObjectWithDefaults(page, {
|
const swgD = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
const swgE = await createDomainObjectWithDefaults(page, {
|
const swgE = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -152,9 +171,15 @@ test.describe('Overlay Plot', () => {
|
|||||||
await selectInspectorTab(page, 'Elements');
|
await selectInspectorTab(page, 'Elements');
|
||||||
|
|
||||||
// Drag swg a, c, e into Y Axis 2
|
// Drag swg a, c, e into Y Axis 2
|
||||||
await page.locator(`#inspector-elements-tree >> text=${swgA.name}`).dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
await page
|
||||||
await page.locator(`#inspector-elements-tree >> text=${swgC.name}`).dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
.locator(`#inspector-elements-tree >> text=${swgA.name}`)
|
||||||
await page.locator(`#inspector-elements-tree >> text=${swgE.name}`).dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
||||||
|
await page
|
||||||
|
.locator(`#inspector-elements-tree >> text=${swgC.name}`)
|
||||||
|
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
||||||
|
await page
|
||||||
|
.locator(`#inspector-elements-tree >> text=${swgE.name}`)
|
||||||
|
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
|
||||||
|
|
||||||
// Assert that Y Axis 1 and Y Axis 2 property groups are visible only
|
// Assert that Y Axis 1 and Y Axis 2 property groups are visible only
|
||||||
await selectInspectorTab(page, 'Config');
|
await selectInspectorTab(page, 'Config');
|
||||||
@ -167,14 +192,16 @@ test.describe('Overlay Plot', () => {
|
|||||||
await expect(yAxis2PropertyGroup).toBeVisible();
|
await expect(yAxis2PropertyGroup).toBeVisible();
|
||||||
await expect(yAxis3PropertyGroup).toBeHidden();
|
await expect(yAxis3PropertyGroup).toBeHidden();
|
||||||
|
|
||||||
const yAxis1Group = page.getByLabel("Y Axis 1");
|
const yAxis1Group = page.getByLabel('Y Axis 1');
|
||||||
const yAxis2Group = page.getByLabel("Y Axis 2");
|
const yAxis2Group = page.getByLabel('Y Axis 2');
|
||||||
const yAxis3Group = page.getByLabel("Y Axis 3");
|
const yAxis3Group = page.getByLabel('Y Axis 3');
|
||||||
|
|
||||||
await selectInspectorTab(page, 'Elements');
|
await selectInspectorTab(page, 'Elements');
|
||||||
|
|
||||||
// Drag swg b into Y Axis 3
|
// Drag swg b into Y Axis 3
|
||||||
await page.locator(`#inspector-elements-tree >> text=${swgB.name}`).dragTo(page.locator('[aria-label="Element Item Group Y Axis 3"]'));
|
await page
|
||||||
|
.locator(`#inspector-elements-tree >> text=${swgB.name}`)
|
||||||
|
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 3"]'));
|
||||||
|
|
||||||
// Assert that all Y Axis property groups are visible
|
// Assert that all Y Axis property groups are visible
|
||||||
await selectInspectorTab(page, 'Config');
|
await selectInspectorTab(page, 'Config');
|
||||||
@ -198,13 +225,15 @@ test.describe('Overlay Plot', () => {
|
|||||||
expect(yAxis3Group.getByRole('listitem').nth(0).getByText(swgB.name)).toBeTruthy();
|
expect(yAxis3Group.getByRole('listitem').nth(0).getByText(swgB.name)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Clicking on an item in the elements pool brings up the plot preview with data points', async ({ page }) => {
|
test('Clicking on an item in the elements pool brings up the plot preview with data points', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Overlay Plot"
|
type: 'Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
const swgA = await createDomainObjectWithDefaults(page, {
|
const swgA = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite is dedicated to testing the rendering and interaction of plots.
|
* This test suite is dedicated to testing the rendering and interaction of plots.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, getCanvasPixels } = require('../../../../appActions');
|
const { createDomainObjectWithDefaults, getCanvasPixels } = require('../../../../appActions');
|
||||||
@ -34,7 +34,9 @@ test.describe('Plot Rendering', () => {
|
|||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
// Open a browser, navigate to the main page, and wait until all networkevents to resolve
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
sineWaveGeneratorObject = await createDomainObjectWithDefaults(page, { type: 'Sine Wave Generator' });
|
sineWaveGeneratorObject = await createDomainObjectWithDefaults(page, {
|
||||||
|
type: 'Sine Wave Generator'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Plots do not re-request data when a plot is clicked', async ({ page }) => {
|
test('Plots do not re-request data when a plot is clicked', async ({ page }) => {
|
||||||
@ -44,7 +46,7 @@ test.describe('Plot Rendering', () => {
|
|||||||
await page.locator('canvas').nth(1).click();
|
await page.locator('canvas').nth(1).click();
|
||||||
// No request was made to get historical data
|
// No request was made to get historical data
|
||||||
const createMineFolderRequests = [];
|
const createMineFolderRequests = [];
|
||||||
page.on('request', req => {
|
page.on('request', (req) => {
|
||||||
createMineFolderRequests.push(req);
|
createMineFolderRequests.push(req);
|
||||||
});
|
});
|
||||||
expect(createMineFolderRequests.length).toEqual(0);
|
expect(createMineFolderRequests.length).toEqual(0);
|
||||||
@ -73,13 +75,17 @@ async function editSineWaveToUseInfinityOption(page, sineWaveGeneratorObject) {
|
|||||||
// Edit SWG properties to include infinity values
|
// Edit SWG properties to include infinity values
|
||||||
await page.locator('[title="More options"]').click();
|
await page.locator('[title="More options"]').click();
|
||||||
await page.locator('[title="Edit properties of this object."]').click();
|
await page.locator('[title="Edit properties of this object."]').click();
|
||||||
await page.getByRole('switch', {
|
await page
|
||||||
name: "Include Infinity Values"
|
.getByRole('switch', {
|
||||||
}).check();
|
name: 'Include Infinity Values'
|
||||||
|
})
|
||||||
|
.check();
|
||||||
|
|
||||||
await page.getByRole('button', {
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
name: 'Save'
|
name: 'Save'
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
// FIXME: Changes to SWG properties should be reflected on save, but they're not?
|
// FIXME: Changes to SWG properties should be reflected on save, but they're not?
|
||||||
// Thus, navigate away and back to the object.
|
// Thus, navigate away and back to the object.
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This test suite is dedicated to testing the Scatter Plot component.
|
* This test suite is dedicated to testing the Scatter Plot component.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, selectInspectorTab } = require('../../../../appActions');
|
const { createDomainObjectWithDefaults, selectInspectorTab } = require('../../../../appActions');
|
||||||
@ -67,7 +67,13 @@ test.describe('Scatter Plot', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Verify that the 'Replace telemetry source' modal appears and accept it
|
// Verify that the 'Replace telemetry source' modal appears and accept it
|
||||||
await expect.soft(page.locator('text=This action will replace the current telemetry source. Do you want to continue?')).toBeVisible();
|
await expect
|
||||||
|
.soft(
|
||||||
|
page.locator(
|
||||||
|
'text=This action will replace the current telemetry source. Do you want to continue?'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toBeVisible();
|
||||||
await page.click('text=Ok');
|
await page.click('text=Ok');
|
||||||
|
|
||||||
// Navigate to the scatter plot and verify that the new SWG
|
// Navigate to the scatter plot and verify that the new SWG
|
||||||
@ -88,7 +94,13 @@ test.describe('Scatter Plot', () => {
|
|||||||
await page.locator('li[title="Remove this object from its containing object."]').click();
|
await page.locator('li[title="Remove this object from its containing object."]').click();
|
||||||
|
|
||||||
// Verify that the 'Remove object' confirmation modal appears and accept it
|
// Verify that the 'Remove object' confirmation modal appears and accept it
|
||||||
await expect.soft(page.locator('text=Warning! This action will remove this object. Are you sure you want to continue?')).toBeVisible();
|
await expect
|
||||||
|
.soft(
|
||||||
|
page.locator(
|
||||||
|
'text=Warning! This action will remove this object. Are you sure you want to continue?'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toBeVisible();
|
||||||
await page.click('text=Ok');
|
await page.click('text=Ok');
|
||||||
|
|
||||||
// Verify that the elements pool shows no elements
|
// Verify that the elements pool shows no elements
|
||||||
|
@ -39,27 +39,33 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
stackedPlot = await createDomainObjectWithDefaults(page, {
|
stackedPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Stacked Plot"
|
type: 'Stacked Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
swgA = await createDomainObjectWithDefaults(page, {
|
swgA = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
swgB = await createDomainObjectWithDefaults(page, {
|
swgB = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
swgC = await createDomainObjectWithDefaults(page, {
|
swgC = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Using the remove action removes the correct plot', async ({ page }) => {
|
test('Using the remove action removes the correct plot', async ({ page }) => {
|
||||||
const swgAElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgA.name });
|
const swgAElementsPoolItem = page
|
||||||
const swgBElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgB.name });
|
.locator('#inspector-elements-tree')
|
||||||
const swgCElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgC.name });
|
.locator('.c-object-label', { hasText: swgA.name });
|
||||||
|
const swgBElementsPoolItem = page
|
||||||
|
.locator('#inspector-elements-tree')
|
||||||
|
.locator('.c-object-label', { hasText: swgB.name });
|
||||||
|
const swgCElementsPoolItem = page
|
||||||
|
.locator('#inspector-elements-tree')
|
||||||
|
.locator('.c-object-label', { hasText: swgC.name });
|
||||||
|
|
||||||
await page.goto(stackedPlot.url);
|
await page.goto(stackedPlot.url);
|
||||||
|
|
||||||
@ -68,8 +74,11 @@ test.describe('Stacked Plot', () => {
|
|||||||
await selectInspectorTab(page, 'Elements');
|
await selectInspectorTab(page, 'Elements');
|
||||||
|
|
||||||
await swgBElementsPoolItem.click({ button: 'right' });
|
await swgBElementsPoolItem.click({ button: 'right' });
|
||||||
await page.getByRole('menuitem').filter({ hasText: /Remove/ }).click();
|
await page
|
||||||
await page.getByRole('button').filter({ hasText: "OK" }).click();
|
.getByRole('menuitem')
|
||||||
|
.filter({ hasText: /Remove/ })
|
||||||
|
.click();
|
||||||
|
await page.getByRole('button').filter({ hasText: 'OK' }).click();
|
||||||
|
|
||||||
await expect(page.locator('#inspector-elements-tree .js-elements-pool__item')).toHaveCount(2);
|
await expect(page.locator('#inspector-elements-tree .js-elements-pool__item')).toHaveCount(2);
|
||||||
|
|
||||||
@ -80,9 +89,15 @@ test.describe('Stacked Plot', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can reorder Stacked Plot items', async ({ page }) => {
|
test('Can reorder Stacked Plot items', async ({ page }) => {
|
||||||
const swgAElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgA.name });
|
const swgAElementsPoolItem = page
|
||||||
const swgBElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgB.name });
|
.locator('#inspector-elements-tree')
|
||||||
const swgCElementsPoolItem = page.locator('#inspector-elements-tree').locator('.c-object-label', { hasText: swgC.name });
|
.locator('.c-object-label', { hasText: swgA.name });
|
||||||
|
const swgBElementsPoolItem = page
|
||||||
|
.locator('#inspector-elements-tree')
|
||||||
|
.locator('.c-object-label', { hasText: swgB.name });
|
||||||
|
const swgCElementsPoolItem = page
|
||||||
|
.locator('#inspector-elements-tree')
|
||||||
|
.locator('.c-object-label', { hasText: swgC.name });
|
||||||
|
|
||||||
await page.goto(stackedPlot.url);
|
await page.goto(stackedPlot.url);
|
||||||
|
|
||||||
@ -128,7 +143,9 @@ test.describe('Stacked Plot', () => {
|
|||||||
await expect(stackedPlotItem3).toHaveAttribute('aria-label', `Stacked Plot Item ${swgA.name}`);
|
await expect(stackedPlotItem3).toHaveAttribute('aria-label', `Stacked Plot Item ${swgA.name}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Selecting a child plot while in browse and edit modes shows its properties in the inspector', async ({ page }) => {
|
test('Selecting a child plot while in browse and edit modes shows its properties in the inspector', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
await page.goto(stackedPlot.url);
|
await page.goto(stackedPlot.url);
|
||||||
|
|
||||||
await selectInspectorTab(page, 'Config');
|
await selectInspectorTab(page, 'Config');
|
||||||
@ -137,25 +154,37 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"] canvas`).nth(1).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"] canvas`).nth(1).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgA
|
// Assert that the inspector shows the Y Axis properties for swgA
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
await expect(page.getByRole('heading', { name: "Y Axis" })).toBeVisible();
|
'Plot Series'
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgA.name);
|
);
|
||||||
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgA.name);
|
||||||
|
|
||||||
// Click on the 2nd plot
|
// Click on the 2nd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"] canvas`).nth(1).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"] canvas`).nth(1).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgB
|
// Assert that the inspector shows the Y Axis properties for swgB
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
|
'Plot Series'
|
||||||
|
);
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgB.name);
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgB.name);
|
||||||
|
|
||||||
// Click on the 3rd plot
|
// Click on the 3rd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"] canvas`).nth(1).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"] canvas`).nth(1).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgC
|
// Assert that the inspector shows the Y Axis properties for swgC
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
|
'Plot Series'
|
||||||
|
);
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgC.name);
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgC.name);
|
||||||
|
|
||||||
// Go into edit mode
|
// Go into edit mode
|
||||||
await page.click('button[title="Edit"]');
|
await page.click('button[title="Edit"]');
|
||||||
@ -166,24 +195,36 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"]`).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"]`).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgA
|
// Assert that the inspector shows the Y Axis properties for swgA
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
|
'Plot Series'
|
||||||
|
);
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgA.name);
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgA.name);
|
||||||
|
|
||||||
//Click on canvas for the 2nd plot
|
//Click on canvas for the 2nd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"]`).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"]`).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgB
|
// Assert that the inspector shows the Y Axis properties for swgB
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
|
'Plot Series'
|
||||||
|
);
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgB.name);
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgB.name);
|
||||||
|
|
||||||
//Click on canvas for the 3rd plot
|
//Click on canvas for the 3rd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"]`).click();
|
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"]`).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgC
|
// Assert that the inspector shows the Y Axis properties for swgC
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText("Plot Series");
|
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
||||||
|
'Plot Series'
|
||||||
|
);
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] .c-object-label')).toContainText(swgC.name);
|
await expect(
|
||||||
|
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
||||||
|
).toContainText(swgC.name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,12 @@ Tests to verify plot tagging functionality.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults, setRealTimeMode, setFixedTimeMode, waitForPlotsToRender } = require('../../../../appActions');
|
const {
|
||||||
|
createDomainObjectWithDefaults,
|
||||||
|
setRealTimeMode,
|
||||||
|
setFixedTimeMode,
|
||||||
|
waitForPlotsToRender
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Plot Tagging', () => {
|
test.describe('Plot Tagging', () => {
|
||||||
/**
|
/**
|
||||||
@ -36,8 +41,8 @@ test.describe('Plot Tagging', () => {
|
|||||||
* @param {Number} yEnd a telemetry item with a plot
|
* @param {Number} yEnd a telemetry item with a plot
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
async function createTags({page, canvas, xEnd, yEnd}) {
|
async function createTags({ page, canvas, xEnd, yEnd }) {
|
||||||
await canvas.hover({trial: true});
|
await canvas.hover({ trial: true });
|
||||||
|
|
||||||
//Alt+Shift Drag Start to select some points to tag
|
//Alt+Shift Drag Start to select some points to tag
|
||||||
await page.keyboard.down('Alt');
|
await page.keyboard.down('Alt');
|
||||||
@ -59,7 +64,7 @@ test.describe('Plot Tagging', () => {
|
|||||||
await page.keyboard.up('Shift');
|
await page.keyboard.up('Shift');
|
||||||
|
|
||||||
//Wait for canvas to stablize.
|
//Wait for canvas to stablize.
|
||||||
await canvas.hover({trial: true});
|
await canvas.hover({ trial: true });
|
||||||
|
|
||||||
// add some tags
|
// add some tags
|
||||||
await page.getByText('Annotations').click();
|
await page.getByText('Annotations').click();
|
||||||
@ -87,7 +92,7 @@ test.describe('Plot Tagging', () => {
|
|||||||
const canvas = page.locator('canvas').nth(1);
|
const canvas = page.locator('canvas').nth(1);
|
||||||
|
|
||||||
//Wait for canvas to stablize.
|
//Wait for canvas to stablize.
|
||||||
await canvas.hover({trial: true});
|
await canvas.hover({ trial: true });
|
||||||
|
|
||||||
// click on the tagged plot point
|
// click on the tagged plot point
|
||||||
await canvas.click({
|
await canvas.click({
|
||||||
@ -115,7 +120,11 @@ test.describe('Plot Tagging', () => {
|
|||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('driv');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('driv');
|
||||||
// click on the search result
|
// click on the search result
|
||||||
await page.getByRole('searchbox', { name: 'OpenMCT Search' }).getByText(/Sine Wave/).first().click();
|
await page
|
||||||
|
.getByRole('searchbox', { name: 'OpenMCT Search' })
|
||||||
|
.getByText(/Sine Wave/)
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
|
||||||
// Delete Driving
|
// Delete Driving
|
||||||
await page.hover('[aria-label="Tag"]:has-text("Driving")');
|
await page.hover('[aria-label="Tag"]:has-text("Driving")');
|
||||||
@ -124,8 +133,8 @@ test.describe('Plot Tagging', () => {
|
|||||||
// Search for Science
|
// Search for Science
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
||||||
await expect(page.locator('[aria-label="Search Result"]').nth(0)).toContainText("Science");
|
await expect(page.locator('[aria-label="Search Result"]').nth(0)).toContainText('Science');
|
||||||
await expect(page.locator('[aria-label="Search Result"]').nth(0)).not.toContainText("Drilling");
|
await expect(page.locator('[aria-label="Search Result"]').nth(0)).not.toContainText('Drilling');
|
||||||
|
|
||||||
// Search for Driving
|
// Search for Driving
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
@ -162,18 +171,18 @@ test.describe('Plot Tagging', () => {
|
|||||||
test.slow();
|
test.slow();
|
||||||
|
|
||||||
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
const overlayPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Overlay Plot"
|
type: 'Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
const alphaSineWave = await createDomainObjectWithDefaults(page, {
|
const alphaSineWave = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
name: "Alpha Sine Wave",
|
name: 'Alpha Sine Wave',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
name: "Beta Sine Wave",
|
name: 'Beta Sine Wave',
|
||||||
parent: overlayPlot.uuid
|
parent: overlayPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -204,7 +213,11 @@ test.describe('Plot Tagging', () => {
|
|||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
|
||||||
// click on the search result
|
// click on the search result
|
||||||
await page.getByRole('searchbox', { name: 'OpenMCT Search' }).getByText('Alpha Sine Wave').first().click();
|
await page
|
||||||
|
.getByRole('searchbox', { name: 'OpenMCT Search' })
|
||||||
|
.getByText('Alpha Sine Wave')
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
// wait for plots to load
|
// wait for plots to load
|
||||||
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
|
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
|
||||||
// expect plot to be paused
|
// expect plot to be paused
|
||||||
@ -215,7 +228,7 @@ test.describe('Plot Tagging', () => {
|
|||||||
|
|
||||||
test('Tags work with Plot View of telemetry items', async ({ page }) => {
|
test('Tags work with Plot View of telemetry items', async ({ page }) => {
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator"
|
type: 'Sine Wave Generator'
|
||||||
});
|
});
|
||||||
|
|
||||||
const canvas = page.locator('canvas').nth(1);
|
const canvas = page.locator('canvas').nth(1);
|
||||||
@ -230,18 +243,18 @@ test.describe('Plot Tagging', () => {
|
|||||||
|
|
||||||
test('Tags work with Stacked Plots', async ({ page }) => {
|
test('Tags work with Stacked Plots', async ({ page }) => {
|
||||||
const stackedPlot = await createDomainObjectWithDefaults(page, {
|
const stackedPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Stacked Plot"
|
type: 'Stacked Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
const alphaSineWave = await createDomainObjectWithDefaults(page, {
|
const alphaSineWave = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
name: "Alpha Sine Wave",
|
name: 'Alpha Sine Wave',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: "Sine Wave Generator",
|
type: 'Sine Wave Generator',
|
||||||
name: "Beta Sine Wave",
|
name: 'Beta Sine Wave',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,7 +24,9 @@ const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
|||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
|
|
||||||
test.describe('Telemetry Table', () => {
|
test.describe('Telemetry Table', () => {
|
||||||
test('unpauses and filters data when paused by button and user changes bounds', async ({ page }) => {
|
test('unpauses and filters data when paused by button and user changes bounds', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5113'
|
description: 'https://github.com/nasa/openmct/issues/5113'
|
||||||
@ -65,7 +67,12 @@ test.describe('Telemetry Table', () => {
|
|||||||
await expect(tableWrapper).not.toHaveClass(/is-paused/);
|
await expect(tableWrapper).not.toHaveClass(/is-paused/);
|
||||||
|
|
||||||
// Get the most recent telemetry date
|
// Get the most recent telemetry date
|
||||||
const latestTelemetryDate = await page.locator('table.c-telemetry-table__body > tbody > tr').last().locator('td').nth(1).getAttribute('title');
|
const latestTelemetryDate = await page
|
||||||
|
.locator('table.c-telemetry-table__body > tbody > tr')
|
||||||
|
.last()
|
||||||
|
.locator('td')
|
||||||
|
.nth(1)
|
||||||
|
.getAttribute('title');
|
||||||
|
|
||||||
// Verify that it is <= our new end bound
|
// Verify that it is <= our new end bound
|
||||||
const latestMilliseconds = Date.parse(latestTelemetryDate);
|
const latestMilliseconds = Date.parse(latestTelemetryDate);
|
||||||
|
@ -21,7 +21,12 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { setFixedTimeMode, setRealTimeMode, setStartOffset, setEndOffset } = require('../../../../appActions');
|
const {
|
||||||
|
setFixedTimeMode,
|
||||||
|
setRealTimeMode,
|
||||||
|
setStartOffset,
|
||||||
|
setEndOffset
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Time conductor operations', () => {
|
test.describe('Time conductor operations', () => {
|
||||||
test('validate start time does not exceeds end time', async ({ page }) => {
|
test('validate start time does not exceeds end time', async ({ page }) => {
|
||||||
@ -48,23 +53,27 @@ test.describe('Time conductor operations', () => {
|
|||||||
await startTimeLocator.fill(startDate.toString());
|
await startTimeLocator.fill(startDate.toString());
|
||||||
|
|
||||||
// invalid start date
|
// invalid start date
|
||||||
startDate = (year + 1) + startDate.substring(4);
|
startDate = year + 1 + startDate.substring(4);
|
||||||
await startTimeLocator.fill(startDate.toString());
|
await startTimeLocator.fill(startDate.toString());
|
||||||
await endTimeLocator.click();
|
await endTimeLocator.click();
|
||||||
|
|
||||||
const startDateValidityStatus = await startTimeLocator.evaluate((element) => element.checkValidity());
|
const startDateValidityStatus = await startTimeLocator.evaluate((element) =>
|
||||||
|
element.checkValidity()
|
||||||
|
);
|
||||||
expect(startDateValidityStatus).not.toBeTruthy();
|
expect(startDateValidityStatus).not.toBeTruthy();
|
||||||
|
|
||||||
// fix to valid start date
|
// fix to valid start date
|
||||||
startDate = (year - 1) + startDate.substring(4);
|
startDate = year - 1 + startDate.substring(4);
|
||||||
await startTimeLocator.fill(startDate.toString());
|
await startTimeLocator.fill(startDate.toString());
|
||||||
|
|
||||||
// invalid end date
|
// invalid end date
|
||||||
endDate = (year - 2) + endDate.substring(4);
|
endDate = year - 2 + endDate.substring(4);
|
||||||
await endTimeLocator.fill(endDate.toString());
|
await endTimeLocator.fill(endDate.toString());
|
||||||
await startTimeLocator.click();
|
await startTimeLocator.click();
|
||||||
|
|
||||||
const endDateValidityStatus = await endTimeLocator.evaluate((element) => element.checkValidity());
|
const endDateValidityStatus = await endTimeLocator.evaluate((element) =>
|
||||||
|
element.checkValidity()
|
||||||
|
);
|
||||||
expect(endDateValidityStatus).not.toBeTruthy();
|
expect(endDateValidityStatus).not.toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -91,7 +100,9 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
await setStartOffset(page, startOffset);
|
await setStartOffset(page, startOffset);
|
||||||
|
|
||||||
// Verify time was updated on time offset button
|
// Verify time was updated on time offset button
|
||||||
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText('00:30:23');
|
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText(
|
||||||
|
'00:30:23'
|
||||||
|
);
|
||||||
|
|
||||||
// Set end time offset
|
// Set end time offset
|
||||||
await setEndOffset(page, endOffset);
|
await setEndOffset(page, endOffset);
|
||||||
@ -104,7 +115,9 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
* Verify that offsets and url params are preserved when switching
|
* Verify that offsets and url params are preserved when switching
|
||||||
* between fixed timespan and real-time mode.
|
* between fixed timespan and real-time mode.
|
||||||
*/
|
*/
|
||||||
test('preserve offsets and url params when switching between fixed and real-time mode', async ({ page }) => {
|
test('preserve offsets and url params when switching between fixed and real-time mode', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
const startOffset = {
|
const startOffset = {
|
||||||
mins: '30',
|
mins: '30',
|
||||||
secs: '23'
|
secs: '23'
|
||||||
@ -115,8 +128,8 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Convert offsets to milliseconds
|
// Convert offsets to milliseconds
|
||||||
const startDelta = (30 * 60 * 1000) + (23 * 1000);
|
const startDelta = 30 * 60 * 1000 + 23 * 1000;
|
||||||
const endDelta = (1 * 1000);
|
const endDelta = 1 * 1000;
|
||||||
|
|
||||||
// Go to baseURL
|
// Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
@ -137,7 +150,9 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
await setRealTimeMode(page);
|
await setRealTimeMode(page);
|
||||||
|
|
||||||
// Verify updated start time offset persists after mode switch
|
// Verify updated start time offset persists after mode switch
|
||||||
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText('00:30:23');
|
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText(
|
||||||
|
'00:30:23'
|
||||||
|
);
|
||||||
|
|
||||||
// Verify updated end time offset persists after mode switch
|
// Verify updated end time offset persists after mode switch
|
||||||
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
|
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
|
||||||
@ -148,20 +163,29 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
expect(page.url()).toContain(`endDelta=${endDelta}`);
|
expect(page.url()).toContain(`endDelta=${endDelta}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme('time conductor history in fixed time mode will track changing start and end times', async ({ page }) => {
|
test.fixme(
|
||||||
|
'time conductor history in fixed time mode will track changing start and end times',
|
||||||
|
async ({ page }) => {
|
||||||
// change start time, verify it's tracked in history
|
// change start time, verify it's tracked in history
|
||||||
// change end time, verify it's tracked in history
|
// change end time, verify it's tracked in history
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
test.fixme('time conductor history in realtime mode will track changing start and end times', async ({ page }) => {
|
test.fixme(
|
||||||
|
'time conductor history in realtime mode will track changing start and end times',
|
||||||
|
async ({ page }) => {
|
||||||
// change start offset, verify it's tracked in history
|
// change start offset, verify it's tracked in history
|
||||||
// change end offset, verify it's tracked in history
|
// change end offset, verify it's tracked in history
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
test.fixme('time conductor history allows you to set a historical timeframe', async ({ page }) => {
|
test.fixme(
|
||||||
|
'time conductor history allows you to set a historical timeframe',
|
||||||
|
async ({ page }) => {
|
||||||
// make sure there are historical history options
|
// make sure there are historical history options
|
||||||
// select an option and make sure the time conductor start and end bounds are updated correctly
|
// select an option and make sure the time conductor start and end bounds are updated correctly
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
test.fixme('time conductor history allows you to set a realtime offsets', async ({ page }) => {
|
test.fixme('time conductor history allows you to set a realtime offsets', async ({ page }) => {
|
||||||
// make sure there are realtime history options
|
// make sure there are realtime history options
|
||||||
@ -170,7 +194,7 @@ test.describe('Time conductor input fields real-time mode', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Time Conductor History', () => {
|
test.describe('Time Conductor History', () => {
|
||||||
test("shows milliseconds on hover @unstable", async ({ page }) => {
|
test('shows milliseconds on hover @unstable', async ({ page }) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/4386'
|
description: 'https://github.com/nasa/openmct/issues/4386'
|
||||||
@ -178,13 +202,19 @@ test.describe('Time Conductor History', () => {
|
|||||||
// Navigate to Open MCT in Fixed Time Mode, UTC Time System
|
// Navigate to Open MCT in Fixed Time Mode, UTC Time System
|
||||||
// with startBound at 2022-01-01 00:00:00.000Z
|
// with startBound at 2022-01-01 00:00:00.000Z
|
||||||
// and endBound at 2022-01-01 00:00:00.200Z
|
// and endBound at 2022-01-01 00:00:00.200Z
|
||||||
await page.goto('./#/browse/mine?view=grid&tc.mode=fixed&tc.startBound=1640995200000&tc.endBound=1640995200200&tc.timeSystem=utc&hideInspector=true', { waitUntil: 'networkidle' });
|
await page.goto(
|
||||||
await page.locator("[aria-label='Time Conductor History']").hover({ trial: true});
|
'./#/browse/mine?view=grid&tc.mode=fixed&tc.startBound=1640995200000&tc.endBound=1640995200200&tc.timeSystem=utc&hideInspector=true',
|
||||||
|
{ waitUntil: 'networkidle' }
|
||||||
|
);
|
||||||
|
await page.locator("[aria-label='Time Conductor History']").hover({ trial: true });
|
||||||
await page.locator("[aria-label='Time Conductor History']").click();
|
await page.locator("[aria-label='Time Conductor History']").click();
|
||||||
|
|
||||||
// Validate history item format
|
// Validate history item format
|
||||||
const historyItem = page.locator('text="2022-01-01 00:00:00 + 200ms"');
|
const historyItem = page.locator('text="2022-01-01 00:00:00 + 200ms"');
|
||||||
await expect(historyItem).toBeEnabled();
|
await expect(historyItem).toBeEnabled();
|
||||||
await expect(historyItem).toHaveAttribute('title', '2022-01-01 00:00:00.000 - 2022-01-01 00:00:00.200');
|
await expect(historyItem).toHaveAttribute(
|
||||||
|
'title',
|
||||||
|
'2022-01-01 00:00:00.000 - 2022-01-01 00:00:00.200'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,10 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { openObjectTreeContextMenu, createDomainObjectWithDefaults } = require('../../../../appActions');
|
const {
|
||||||
|
openObjectTreeContextMenu,
|
||||||
|
createDomainObjectWithDefaults
|
||||||
|
} = require('../../../../appActions');
|
||||||
|
|
||||||
test.describe('Timer', () => {
|
test.describe('Timer', () => {
|
||||||
let timer;
|
let timer;
|
||||||
@ -38,21 +41,21 @@ test.describe('Timer', () => {
|
|||||||
|
|
||||||
const timerUrl = timer.url;
|
const timerUrl = timer.url;
|
||||||
|
|
||||||
await test.step("From the tree context menu", async () => {
|
await test.step('From the tree context menu', async () => {
|
||||||
await triggerTimerContextMenuAction(page, timerUrl, 'Start');
|
await triggerTimerContextMenuAction(page, timerUrl, 'Start');
|
||||||
await triggerTimerContextMenuAction(page, timerUrl, 'Pause');
|
await triggerTimerContextMenuAction(page, timerUrl, 'Pause');
|
||||||
await triggerTimerContextMenuAction(page, timerUrl, 'Restart at 0');
|
await triggerTimerContextMenuAction(page, timerUrl, 'Restart at 0');
|
||||||
await triggerTimerContextMenuAction(page, timerUrl, 'Stop');
|
await triggerTimerContextMenuAction(page, timerUrl, 'Stop');
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("From the 3dot menu", async () => {
|
await test.step('From the 3dot menu', async () => {
|
||||||
await triggerTimer3dotMenuAction(page, 'Start');
|
await triggerTimer3dotMenuAction(page, 'Start');
|
||||||
await triggerTimer3dotMenuAction(page, 'Pause');
|
await triggerTimer3dotMenuAction(page, 'Pause');
|
||||||
await triggerTimer3dotMenuAction(page, 'Restart at 0');
|
await triggerTimer3dotMenuAction(page, 'Restart at 0');
|
||||||
await triggerTimer3dotMenuAction(page, 'Stop');
|
await triggerTimer3dotMenuAction(page, 'Stop');
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("From the object view", async () => {
|
await test.step('From the object view', async () => {
|
||||||
await triggerTimerViewAction(page, 'Start');
|
await triggerTimerViewAction(page, 'Start');
|
||||||
await triggerTimerViewAction(page, 'Pause');
|
await triggerTimerViewAction(page, 'Pause');
|
||||||
await triggerTimerViewAction(page, 'Restart at 0');
|
await triggerTimerViewAction(page, 'Restart at 0');
|
||||||
@ -111,7 +114,7 @@ async function triggerTimer3dotMenuAction(page, action) {
|
|||||||
* @param {TimerViewAction} action
|
* @param {TimerViewAction} action
|
||||||
*/
|
*/
|
||||||
async function triggerTimerViewAction(page, action) {
|
async function triggerTimerViewAction(page, action) {
|
||||||
await page.locator('.c-timer').hover({trial: true});
|
await page.locator('.c-timer').hover({ trial: true });
|
||||||
const buttonTitle = buttonTitleFromAction(action);
|
const buttonTitle = buttonTitleFromAction(action);
|
||||||
await page.click(`button[title="${buttonTitle}"]`);
|
await page.click(`button[title="${buttonTitle}"]`);
|
||||||
assertTimerStateAfterAction(page, action);
|
assertTimerStateAfterAction(page, action);
|
||||||
@ -142,7 +145,7 @@ async function assertTimerStateAfterAction(page, action) {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case 'Start':
|
case 'Start':
|
||||||
case 'Restart at 0':
|
case 'Restart at 0':
|
||||||
timerStateClass = "is-started";
|
timerStateClass = 'is-started';
|
||||||
break;
|
break;
|
||||||
case 'Stop':
|
case 'Stop':
|
||||||
timerStateClass = 'is-stopped';
|
timerStateClass = 'is-stopped';
|
||||||
|
@ -49,14 +49,19 @@ test.describe('Recent Objects', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Drag the Recent Objects panel up a bit
|
// Drag the Recent Objects panel up a bit
|
||||||
await page.locator('.l-pane.l-pane--vertical-handle-before', {
|
await page
|
||||||
|
.locator('.l-pane.l-pane--vertical-handle-before', {
|
||||||
hasText: 'Recently Viewed'
|
hasText: 'Recently Viewed'
|
||||||
}).locator('.l-pane__handle').hover();
|
})
|
||||||
|
.locator('.l-pane__handle')
|
||||||
|
.hover();
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
await page.mouse.move(0, 100);
|
await page.mouse.move(0, 100);
|
||||||
await page.mouse.up();
|
await page.mouse.up();
|
||||||
});
|
});
|
||||||
test('Navigated objects show up in recents, object renames and deletions are reflected', async ({ page }) => {
|
test('Navigated objects show up in recents, object renames and deletions are reflected', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
// Verify that both created objects appear in the list and are in the correct order
|
// Verify that both created objects appear in the list and are in the correct order
|
||||||
await assertInitialRecentObjectsListState();
|
await assertInitialRecentObjectsListState();
|
||||||
|
|
||||||
@ -67,22 +72,31 @@ test.describe('Recent Objects', () => {
|
|||||||
|
|
||||||
// Rename
|
// Rename
|
||||||
folderA.name = `${folderA.name}-NEW!`;
|
folderA.name = `${folderA.name}-NEW!`;
|
||||||
await page.locator('.l-browse-bar__object-name').fill("");
|
await page.locator('.l-browse-bar__object-name').fill('');
|
||||||
await page.locator('.l-browse-bar__object-name').fill(folderA.name);
|
await page.locator('.l-browse-bar__object-name').fill(folderA.name);
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
|
|
||||||
// Verify rename has been applied in recent objects list item and objects paths
|
// Verify rename has been applied in recent objects list item and objects paths
|
||||||
expect(await page.getByRole('navigation', {
|
expect(
|
||||||
|
await page
|
||||||
|
.getByRole('navigation', {
|
||||||
name: clock.name
|
name: clock.name
|
||||||
}).locator('a').filter({
|
})
|
||||||
|
.locator('a')
|
||||||
|
.filter({
|
||||||
hasText: folderA.name
|
hasText: folderA.name
|
||||||
}).count()).toBeGreaterThan(0);
|
})
|
||||||
|
.count()
|
||||||
|
).toBeGreaterThan(0);
|
||||||
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeTruthy();
|
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeTruthy();
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
await page.click('button[title="Show selected item in tree"]');
|
await page.click('button[title="Show selected item in tree"]');
|
||||||
// Delete the folder via the left tree pane treeitem context menu
|
// Delete the folder via the left tree pane treeitem context menu
|
||||||
await page.getByRole('treeitem', { name: new RegExp(folderA.name) }).locator('a').click({
|
await page
|
||||||
|
.getByRole('treeitem', { name: new RegExp(folderA.name) })
|
||||||
|
.locator('a')
|
||||||
|
.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
||||||
@ -92,7 +106,10 @@ test.describe('Recent Objects', () => {
|
|||||||
await expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeHidden();
|
await expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeHidden();
|
||||||
await expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeHidden();
|
await expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeHidden();
|
||||||
});
|
});
|
||||||
test("Clicking on an object in the path of a recent object navigates to the object", async ({ page, openmctConfig }) => {
|
test('Clicking on an object in the path of a recent object navigates to the object', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
@ -102,11 +119,15 @@ test.describe('Recent Objects', () => {
|
|||||||
|
|
||||||
// Navigate to the folder by clicking on its entry in the Clock's breadcrumb
|
// Navigate to the folder by clicking on its entry in the Clock's breadcrumb
|
||||||
const waitForFolderNavigation = page.waitForURL(`**/${folderA.uuid}?*`);
|
const waitForFolderNavigation = page.waitForURL(`**/${folderA.uuid}?*`);
|
||||||
await page.getByRole('navigation', {
|
await page
|
||||||
|
.getByRole('navigation', {
|
||||||
name: clock.name
|
name: clock.name
|
||||||
}).locator('a').filter({
|
})
|
||||||
|
.locator('a')
|
||||||
|
.filter({
|
||||||
hasText: folderA.name
|
hasText: folderA.name
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
// Verify that the hash URL updates correctly
|
// Verify that the hash URL updates correctly
|
||||||
await waitForFolderNavigation;
|
await waitForFolderNavigation;
|
||||||
@ -114,26 +135,33 @@ test.describe('Recent Objects', () => {
|
|||||||
|
|
||||||
// Navigate to My Items by clicking on its entry in the Clock's breadcrumb
|
// Navigate to My Items by clicking on its entry in the Clock's breadcrumb
|
||||||
const waitForMyItemsNavigation = page.waitForURL(`**/mine?*`);
|
const waitForMyItemsNavigation = page.waitForURL(`**/mine?*`);
|
||||||
await page.getByRole('navigation', {
|
await page
|
||||||
|
.getByRole('navigation', {
|
||||||
name: clock.name
|
name: clock.name
|
||||||
}).locator('a').filter({
|
})
|
||||||
|
.locator('a')
|
||||||
|
.filter({
|
||||||
hasText: myItemsFolderName
|
hasText: myItemsFolderName
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
// Verify that the hash URL updates correctly
|
// Verify that the hash URL updates correctly
|
||||||
await waitForMyItemsNavigation;
|
await waitForMyItemsNavigation;
|
||||||
expect(page.url()).toMatch(new RegExp(`.*mine?.*`));
|
expect(page.url()).toMatch(new RegExp(`.*mine?.*`));
|
||||||
});
|
});
|
||||||
test("Clicking on the 'target button' scrolls the object into view in the tree and highlights it", async ({ page }) => {
|
test("Clicking on the 'target button' scrolls the object into view in the tree and highlights it", async ({
|
||||||
const clockTreeItem = page.getByRole('tree', { name: 'Main Tree'}).getByRole('treeitem', { name: clock.name });
|
page
|
||||||
const folderTreeItem = page.getByRole('tree', { name: 'Main Tree'})
|
}) => {
|
||||||
.getByRole('treeitem', {
|
const clockTreeItem = page
|
||||||
|
.getByRole('tree', { name: 'Main Tree' })
|
||||||
|
.getByRole('treeitem', { name: clock.name });
|
||||||
|
const folderTreeItem = page.getByRole('tree', { name: 'Main Tree' }).getByRole('treeitem', {
|
||||||
name: folderA.name,
|
name: folderA.name,
|
||||||
expanded: true
|
expanded: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// Click the "Target" button for the Clock which is nested in a folder
|
// Click the "Target" button for the Clock which is nested in a folder
|
||||||
await page.getByRole('button', { name: `Open and scroll to ${clock.name}`}).click();
|
await page.getByRole('button', { name: `Open and scroll to ${clock.name}` }).click();
|
||||||
|
|
||||||
// Assert that the Clock parent folder has expanded and the Clock is visible)
|
// Assert that the Clock parent folder has expanded and the Clock is visible)
|
||||||
await expect(folderTreeItem.locator('.c-disclosure-triangle')).toHaveClass(/--expanded/);
|
await expect(folderTreeItem.locator('.c-disclosure-triangle')).toHaveClass(/--expanded/);
|
||||||
@ -148,50 +176,65 @@ test.describe('Recent Objects', () => {
|
|||||||
// Assert that the Clock treeitem is no longer highlighted
|
// Assert that the Clock treeitem is no longer highlighted
|
||||||
await expect(clockTreeItem.locator('.c-tree__item')).not.toHaveClass(/is-targeted-item/);
|
await expect(clockTreeItem.locator('.c-tree__item')).not.toHaveClass(/is-targeted-item/);
|
||||||
});
|
});
|
||||||
test("Persists on refresh", async ({ page }) => {
|
test('Persists on refresh', async ({ page }) => {
|
||||||
await assertInitialRecentObjectsListState();
|
await assertInitialRecentObjectsListState();
|
||||||
await page.reload();
|
await page.reload();
|
||||||
await assertInitialRecentObjectsListState();
|
await assertInitialRecentObjectsListState();
|
||||||
});
|
});
|
||||||
test("Displays objects and aliases uniquely", async ({ page }) => {
|
test('Displays objects and aliases uniquely', async ({ page }) => {
|
||||||
const mainTree = page.getByRole('tree', { name: 'Main Tree'});
|
const mainTree = page.getByRole('tree', { name: 'Main Tree' });
|
||||||
|
|
||||||
// Navigate to the clock and reveal it in the tree
|
// Navigate to the clock and reveal it in the tree
|
||||||
await page.goto(clock.url);
|
await page.goto(clock.url);
|
||||||
await page.getByTitle('Show selected item in tree').click();
|
await page.getByTitle('Show selected item in tree').click();
|
||||||
|
|
||||||
// Right click the clock and create an alias using the "link" context menu action
|
// Right click the clock and create an alias using the "link" context menu action
|
||||||
const clockTreeItem = page.getByRole('tree', {
|
const clockTreeItem = page
|
||||||
|
.getByRole('tree', {
|
||||||
name: 'Main Tree'
|
name: 'Main Tree'
|
||||||
}).getByRole('treeitem', {
|
})
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: clock.name
|
name: clock.name
|
||||||
});
|
});
|
||||||
await clockTreeItem.click({
|
await clockTreeItem.click({
|
||||||
button: 'right'
|
button: 'right'
|
||||||
});
|
});
|
||||||
await page.getByRole('menuitem', {
|
await page
|
||||||
|
.getByRole('menuitem', {
|
||||||
name: /Create Link/
|
name: /Create Link/
|
||||||
}).click();
|
})
|
||||||
await page.getByRole('tree', { name: 'Create Modal Tree'}).getByRole('treeitem').first().click();
|
.click();
|
||||||
|
await page
|
||||||
|
.getByRole('tree', { name: 'Create Modal Tree' })
|
||||||
|
.getByRole('treeitem')
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
await page.getByRole('button', { name: 'Save' }).click();
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
|
|
||||||
// Click the newly created object alias in the tree
|
// Click the newly created object alias in the tree
|
||||||
await mainTree.getByRole('treeitem', {
|
await mainTree
|
||||||
|
.getByRole('treeitem', {
|
||||||
name: new RegExp(clock.name)
|
name: new RegExp(clock.name)
|
||||||
}).filter({
|
})
|
||||||
|
.filter({
|
||||||
has: page.locator('.is-alias')
|
has: page.locator('.is-alias')
|
||||||
}).click();
|
})
|
||||||
|
.click();
|
||||||
|
|
||||||
// Assert that two recent objects are displayed and one of them is an alias
|
// Assert that two recent objects are displayed and one of them is an alias
|
||||||
expect(await recentObjectsList.getByRole('listitem', { name: clock.name }).count()).toBe(2);
|
expect(await recentObjectsList.getByRole('listitem', { name: clock.name }).count()).toBe(2);
|
||||||
expect(await recentObjectsList.locator('.is-alias').count()).toBe(1);
|
expect(await recentObjectsList.locator('.is-alias').count()).toBe(1);
|
||||||
|
|
||||||
// Assert that the alias and the original's breadcrumbs are different
|
// Assert that the alias and the original's breadcrumbs are different
|
||||||
const clockBreadcrumbs = recentObjectsList.getByRole('listitem', {name: clock.name}).getByRole('navigation');
|
const clockBreadcrumbs = recentObjectsList
|
||||||
|
.getByRole('listitem', { name: clock.name })
|
||||||
|
.getByRole('navigation');
|
||||||
expect(await clockBreadcrumbs.count()).toBe(2);
|
expect(await clockBreadcrumbs.count()).toBe(2);
|
||||||
expect(await clockBreadcrumbs.nth(0).innerText()).not.toEqual(await clockBreadcrumbs.nth(1).innerText());
|
expect(await clockBreadcrumbs.nth(0).innerText()).not.toEqual(
|
||||||
|
await clockBreadcrumbs.nth(1).innerText()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
test("Enforces a limit of 20 recent objects and clears the recent objects", async ({ page }) => {
|
test('Enforces a limit of 20 recent objects and clears the recent objects', async ({ page }) => {
|
||||||
// Creating 21 objects takes a while, so increase the timeout
|
// Creating 21 objects takes a while, so increase the timeout
|
||||||
test.slow();
|
test.slow();
|
||||||
|
|
||||||
@ -203,11 +246,11 @@ test.describe('Recent Objects', () => {
|
|||||||
// Create 19 more objects (3 in beforeEach() + 18 new = 21 total)
|
// Create 19 more objects (3 in beforeEach() + 18 new = 21 total)
|
||||||
for (let i = 0; i < 9; i++) {
|
for (let i = 0; i < 9; i++) {
|
||||||
lastFolder = await createDomainObjectWithDefaults(page, {
|
lastFolder = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Folder",
|
type: 'Folder',
|
||||||
parent: lastFolder?.uuid
|
parent: lastFolder?.uuid
|
||||||
});
|
});
|
||||||
lastClock = await createDomainObjectWithDefaults(page, {
|
lastClock = await createDomainObjectWithDefaults(page, {
|
||||||
type: "Clock",
|
type: 'Clock',
|
||||||
parent: lastFolder?.uuid
|
parent: lastFolder?.uuid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -216,19 +259,17 @@ test.describe('Recent Objects', () => {
|
|||||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(20);
|
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(20);
|
||||||
|
|
||||||
// Collapse the tree
|
// Collapse the tree
|
||||||
await page.getByTitle("Collapse all tree items").click();
|
await page.getByTitle('Collapse all tree items').click();
|
||||||
const lastFolderTreeItem = page.getByRole('tree', { name: 'Main Tree'})
|
const lastFolderTreeItem = page.getByRole('tree', { name: 'Main Tree' }).getByRole('treeitem', {
|
||||||
.getByRole('treeitem', {
|
|
||||||
name: lastFolder.name,
|
name: lastFolder.name,
|
||||||
expanded: true
|
expanded: true
|
||||||
});
|
});
|
||||||
const lastClockTreeItem = page.getByRole('tree', { name: 'Main Tree'})
|
const lastClockTreeItem = page.getByRole('tree', { name: 'Main Tree' }).getByRole('treeitem', {
|
||||||
.getByRole('treeitem', {
|
|
||||||
name: lastClock.name
|
name: lastClock.name
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test "Open and Scroll To" in a deeply nested tree, while we're here
|
// Test "Open and Scroll To" in a deeply nested tree, while we're here
|
||||||
await page.getByRole('button', { name: `Open and scroll to ${lastClock.name}`}).click();
|
await page.getByRole('button', { name: `Open and scroll to ${lastClock.name}` }).click();
|
||||||
|
|
||||||
// Assert that the Clock parent folder has expanded and the Clock is visible)
|
// Assert that the Clock parent folder has expanded and the Clock is visible)
|
||||||
await expect(lastFolderTreeItem.locator('.c-disclosure-triangle')).toHaveClass(/--expanded/);
|
await expect(lastFolderTreeItem.locator('.c-disclosure-triangle')).toHaveClass(/--expanded/);
|
||||||
@ -252,34 +293,28 @@ test.describe('Recent Objects', () => {
|
|||||||
// Assert that the list is empty
|
// Assert that the list is empty
|
||||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(0);
|
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(0);
|
||||||
});
|
});
|
||||||
test("Ensure clear recent objects button is active or inactive", async ({ page }) => {
|
test('Ensure clear recent objects button is active or inactive', async ({ page }) => {
|
||||||
// Assert that the list initially contains 3 objects (clock, folder, my items)
|
// Assert that the list initially contains 3 objects (clock, folder, my items)
|
||||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(3);
|
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(3);
|
||||||
|
|
||||||
// Assert that the button is enabled
|
// Assert that the button is enabled
|
||||||
expect(
|
expect(await page.getByRole('button', { name: 'Clear Recently Viewed' }).isEnabled()).toBe(
|
||||||
await page
|
true
|
||||||
.getByRole("button", { name: "Clear Recently Viewed" })
|
);
|
||||||
.isEnabled()
|
|
||||||
).toBe(true);
|
|
||||||
|
|
||||||
// Click the aria-label="Clear Recently Viewed" button
|
// Click the aria-label="Clear Recently Viewed" button
|
||||||
await page.getByRole("button", { name: "Clear Recently Viewed" }).click();
|
await page.getByRole('button', { name: 'Clear Recently Viewed' }).click();
|
||||||
|
|
||||||
// Click on the "OK" button in the confirmation dialog
|
// Click on the "OK" button in the confirmation dialog
|
||||||
await page.getByRole("button", { name: "OK" }).click();
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
|
||||||
// Assert that the list is empty
|
// Assert that the list is empty
|
||||||
expect(
|
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(0);
|
||||||
await recentObjectsList.locator(".c-recentobjects-listitem").count()
|
|
||||||
).toBe(0);
|
|
||||||
|
|
||||||
// Assert that the button is disabled
|
// Assert that the button is disabled
|
||||||
expect(
|
expect(await page.getByRole('button', { name: 'Clear Recently Viewed' }).isEnabled()).toBe(
|
||||||
await page
|
false
|
||||||
.getByRole("button", { name: "Clear Recently Viewed" })
|
);
|
||||||
.isEnabled()
|
|
||||||
).toBe(false);
|
|
||||||
|
|
||||||
// Navigate to folder object
|
// Navigate to folder object
|
||||||
await page.goto(folderA.url);
|
await page.goto(folderA.url);
|
||||||
@ -288,20 +323,28 @@ test.describe('Recent Objects', () => {
|
|||||||
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(1);
|
expect(await recentObjectsList.locator('.c-recentobjects-listitem').count()).toBe(1);
|
||||||
|
|
||||||
// Assert that the button is enabled
|
// Assert that the button is enabled
|
||||||
expect(
|
expect(await page.getByRole('button', { name: 'Clear Recently Viewed' }).isEnabled()).toBe(
|
||||||
await page
|
true
|
||||||
.getByRole("button", { name: "Clear Recently Viewed" })
|
);
|
||||||
.isEnabled()
|
|
||||||
).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function assertInitialRecentObjectsListState() {
|
function assertInitialRecentObjectsListState() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeVisible(),
|
expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeVisible(),
|
||||||
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeVisible(),
|
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeVisible(),
|
||||||
expect(recentObjectsList.getByRole('listitem', { name: clock.name }).locator('a').getByText(folderA.name)).toBeVisible(),
|
expect(
|
||||||
|
recentObjectsList
|
||||||
|
.getByRole('listitem', { name: clock.name })
|
||||||
|
.locator('a')
|
||||||
|
.getByText(folderA.name)
|
||||||
|
).toBeVisible(),
|
||||||
expect(recentObjectsList.getByRole('listitem').nth(0).getByText(clock.name)).toBeVisible(),
|
expect(recentObjectsList.getByRole('listitem').nth(0).getByText(clock.name)).toBeVisible(),
|
||||||
expect(recentObjectsList.getByRole('listitem', { name: clock.name }).locator('a').getByText(folderA.name)).toBeVisible(),
|
expect(
|
||||||
|
recentObjectsList
|
||||||
|
.getByRole('listitem', { name: clock.name })
|
||||||
|
.locator('a')
|
||||||
|
.getByText(folderA.name)
|
||||||
|
).toBeVisible(),
|
||||||
expect(recentObjectsList.getByRole('listitem').nth(3).getByText(folderA.name)).toBeVisible()
|
expect(recentObjectsList.getByRole('listitem').nth(3).getByText(folderA.name)).toBeVisible()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,13 @@ test.describe('Grand Search', () => {
|
|||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Go to baseURL
|
// Go to baseURL
|
||||||
await page.goto("./", { waitUntil: "networkidle" });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can search for objects, and subsequent search dropdown behaves properly', async ({ page, openmctConfig }) => {
|
test('Can search for objects, and subsequent search dropdown behaves properly', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
|
|
||||||
const createdObjects = await createObjectsForSearch(page);
|
const createdObjects = await createObjectsForSearch(page);
|
||||||
@ -45,10 +48,18 @@ test.describe('Grand Search', () => {
|
|||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
// Fill [aria-label="OpenMCT Search"] input[type="search"]
|
// Fill [aria-label="OpenMCT Search"] input[type="search"]
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Cl');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Cl');
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(`Clock A ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=1')).toContainText(`Clock B ${myItemsFolderName} Red Folder Blue Folder`);
|
`Clock A ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=2')).toContainText(`Clock C ${myItemsFolderName} Red Folder Blue Folder`);
|
);
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(`Clock D ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=1')).toContainText(
|
||||||
|
`Clock B ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
await expect(page.locator('[aria-label="Search Result"] >> nth=2')).toContainText(
|
||||||
|
`Clock C ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(
|
||||||
|
`Clock D ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
// Click the Elements pool to dismiss the search menu
|
// Click the Elements pool to dismiss the search menu
|
||||||
await selectInspectorTab(page, 'Elements');
|
await selectInspectorTab(page, 'Elements');
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
||||||
@ -60,7 +71,9 @@ test.describe('Grand Search', () => {
|
|||||||
// Click [aria-label="Close"]
|
// Click [aria-label="Close"]
|
||||||
await page.locator('[aria-label="Close"]').click();
|
await page.locator('[aria-label="Close"]').click();
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeVisible();
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeVisible();
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(`Clock A ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(
|
||||||
|
`Clock A ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
|
||||||
// Click [aria-label="OpenMCT Search"] a >> nth=0
|
// Click [aria-label="OpenMCT Search"] a >> nth=0
|
||||||
await page.locator('[aria-label="Search Result"] >> nth=0').click();
|
await page.locator('[aria-label="Search Result"] >> nth=0').click();
|
||||||
@ -71,7 +84,10 @@ test.describe('Grand Search', () => {
|
|||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
||||||
|
|
||||||
// Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1
|
// Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
// Click text=Save and Finish Editing
|
// Click text=Save and Finish Editing
|
||||||
await page.locator('text=Save and Finish Editing').click();
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
// Click [aria-label="OpenMCT Search"] [aria-label="Search Input"]
|
// Click [aria-label="OpenMCT Search"] [aria-label="Search Input"]
|
||||||
@ -85,22 +101,34 @@ test.describe('Grand Search', () => {
|
|||||||
await expect(page.locator('.is-object-type-clock')).toBeVisible();
|
await expect(page.locator('.is-object-type-clock')).toBeVisible();
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Disp');
|
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Disp');
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(createdObjects.displayLayout.name);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(
|
||||||
|
createdObjects.displayLayout.name
|
||||||
|
);
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toContainText('Folder');
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toContainText('Folder');
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Clock C');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Clock C');
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(`Clock C ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(
|
||||||
|
`Clock C ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Cloc');
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Cloc');
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(`Clock A ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toContainText(
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=1')).toContainText(`Clock B ${myItemsFolderName} Red Folder Blue Folder`);
|
`Clock A ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=2')).toContainText(`Clock C ${myItemsFolderName} Red Folder Blue Folder`);
|
);
|
||||||
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(`Clock D ${myItemsFolderName} Red Folder Blue Folder`);
|
await expect(page.locator('[aria-label="Search Result"] >> nth=1')).toContainText(
|
||||||
|
`Clock B ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
await expect(page.locator('[aria-label="Search Result"] >> nth=2')).toContainText(
|
||||||
|
`Clock C ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
|
await expect(page.locator('[aria-label="Search Result"] >> nth=3')).toContainText(
|
||||||
|
`Clock D ${myItemsFolderName} Red Folder Blue Folder`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Validate empty search result', async ({ page }) => {
|
test('Validate empty search result', async ({ page }) => {
|
||||||
// Invalid search for objects
|
// Invalid search for objects
|
||||||
await page.type("input[type=search]", 'not found');
|
await page.type('input[type=search]', 'not found');
|
||||||
|
|
||||||
// Wait for search to complete
|
// Wait for search to complete
|
||||||
await waitForSearchCompletion(page);
|
await waitForSearchCompletion(page);
|
||||||
@ -124,7 +152,7 @@ test.describe('Grand Search', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Full search for object
|
// Full search for object
|
||||||
await page.type("input[type=search]", folderName);
|
await page.type('input[type=search]', folderName);
|
||||||
|
|
||||||
// Wait for search to complete
|
// Wait for search to complete
|
||||||
await waitForSearchCompletion(page);
|
await waitForSearchCompletion(page);
|
||||||
@ -155,7 +183,7 @@ test.describe('Grand Search', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Full search for object
|
// Full search for object
|
||||||
await page.type("input[type=search]", 'Clock', { delay: 100 });
|
await page.type('input[type=search]', 'Clock', { delay: 100 });
|
||||||
|
|
||||||
// Wait for search to finish
|
// Wait for search to finish
|
||||||
await waitForSearchCompletion(page);
|
await waitForSearchCompletion(page);
|
||||||
@ -169,15 +197,15 @@ test.describe('Grand Search', () => {
|
|||||||
await expect(searchResultDropDown).toContainText('Clock A');
|
await expect(searchResultDropDown).toContainText('Clock A');
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Validate multiple objects in search results return partial matches", async ({ page }) => {
|
test('Validate multiple objects in search results return partial matches', async ({ page }) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/4667'
|
description: 'https://github.com/nasa/openmct/issues/4667'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create folder objects
|
// Create folder objects
|
||||||
const folderName1 = "e928a26e-e924-4ea0";
|
const folderName1 = 'e928a26e-e924-4ea0';
|
||||||
const folderName2 = "e928a26e-e924-4001";
|
const folderName2 = 'e928a26e-e924-4001';
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Folder',
|
type: 'Folder',
|
||||||
@ -190,7 +218,7 @@ test.describe('Grand Search', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Partial search for objects
|
// Partial search for objects
|
||||||
await page.type("input[type=search]", 'e928a26e');
|
await page.type('input[type=search]', 'e928a26e');
|
||||||
|
|
||||||
// Wait for search to finish
|
// Wait for search to finish
|
||||||
await waitForSearchCompletion(page);
|
await waitForSearchCompletion(page);
|
||||||
|
@ -35,8 +35,9 @@ Make no assumptions about the order that elements appear in the DOM.
|
|||||||
|
|
||||||
const { test, expect } = require('../../pluginFixtures');
|
const { test, expect } = require('../../pluginFixtures');
|
||||||
|
|
||||||
test('Verify that the create button appears and that the Folder Domain Object is available for selection', async ({ page }) => {
|
test('Verify that the create button appears and that the Folder Domain Object is available for selection', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ test.describe('Main Tree', () => {
|
|||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Creating a child object within a folder and immediately opening it shows the created object in the tree @couchdb', async ({ page }) => {
|
test('Creating a child object within a folder and immediately opening it shows the created object in the tree @couchdb', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/5975'
|
description: 'https://github.com/nasa/openmct/issues/5975'
|
||||||
@ -52,7 +54,10 @@ test.describe('Main Tree', () => {
|
|||||||
await assertTreeItemIsVisible(page, clock.name);
|
await assertTreeItemIsVisible(page, clock.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @2p', async ({ page, openmctConfig }) => {
|
test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @2p', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/6391'
|
description: 'https://github.com/nasa/openmct/issues/6391'
|
||||||
@ -75,7 +80,10 @@ test.describe('Main Tree', () => {
|
|||||||
await assertTreeItemIsVisible(page2, page1Folder.name);
|
await assertTreeItemIsVisible(page2, page1Folder.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @couchdb @2p', async ({ page, openmctConfig }) => {
|
test('Creating a child object on one tab and expanding its parent on the other shows the correct composition @couchdb @2p', async ({
|
||||||
|
page,
|
||||||
|
openmctConfig
|
||||||
|
}) => {
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/nasa/openmct/issues/6391'
|
description: 'https://github.com/nasa/openmct/issues/6391'
|
||||||
@ -129,13 +137,13 @@ test.describe('Main Tree', () => {
|
|||||||
// Expand the root folder
|
// Expand the root folder
|
||||||
await expandTreePaneItemByName(page, myItemsFolderName);
|
await expandTreePaneItemByName(page, myItemsFolderName);
|
||||||
|
|
||||||
await test.step("Reorders objects with the same tree depth", async () => {
|
await test.step('Reorders objects with the same tree depth', async () => {
|
||||||
await getAndAssertTreeItems(page, ['aaa', 'Bar', 'Baz', 'Foo', 'www']);
|
await getAndAssertTreeItems(page, ['aaa', 'Bar', 'Baz', 'Foo', 'www']);
|
||||||
await renameObjectFromContextMenu(page, clock1.url, 'zzz');
|
await renameObjectFromContextMenu(page, clock1.url, 'zzz');
|
||||||
await getAndAssertTreeItems(page, ['Bar', 'Baz', 'Foo', 'www', 'zzz']);
|
await getAndAssertTreeItems(page, ['Bar', 'Baz', 'Foo', 'www', 'zzz']);
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step("Reorders links to objects as well as original objects", async () => {
|
await test.step('Reorders links to objects as well as original objects', async () => {
|
||||||
await page.click('role=treeitem[name=/Bar/]');
|
await page.click('role=treeitem[name=/Bar/]');
|
||||||
await page.dragAndDrop('role=treeitem[name=/www/]', '.c-object-view');
|
await page.dragAndDrop('role=treeitem[name=/www/]', '.c-object-view');
|
||||||
await page.dragAndDrop('role=treeitem[name=/zzz/]', '.c-object-view');
|
await page.dragAndDrop('role=treeitem[name=/zzz/]', '.c-object-view');
|
||||||
@ -151,19 +159,18 @@ test.describe('Main Tree', () => {
|
|||||||
await expandTreePaneItemByName(page, 'Foo');
|
await expandTreePaneItemByName(page, 'Foo');
|
||||||
|
|
||||||
await renameObjectFromContextMenu(page, clock1.url, '___');
|
await renameObjectFromContextMenu(page, clock1.url, '___');
|
||||||
await getAndAssertTreeItems(page,
|
await getAndAssertTreeItems(page, [
|
||||||
[
|
'___',
|
||||||
"___",
|
'Bar',
|
||||||
"Bar",
|
'___',
|
||||||
"___",
|
'www',
|
||||||
"www",
|
'Baz',
|
||||||
"Baz",
|
'___',
|
||||||
"___",
|
'www',
|
||||||
"www",
|
'Foo',
|
||||||
"Foo",
|
'___',
|
||||||
"___",
|
'www',
|
||||||
"www",
|
'www'
|
||||||
"www"
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -217,7 +224,7 @@ async function renameObjectFromContextMenu(page, url, newName) {
|
|||||||
await openObjectTreeContextMenu(page, url);
|
await openObjectTreeContextMenu(page, url);
|
||||||
await page.click('li:text("Edit Properties")');
|
await page.click('li:text("Edit Properties")');
|
||||||
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
const nameInput = page.locator('form[name="mctForm"] .first input[type="text"]');
|
||||||
await nameInput.fill("");
|
await nameInput.fill('');
|
||||||
await nameInput.fill(newName);
|
await nameInput.fill(newName);
|
||||||
await page.click('[aria-label="Save"]');
|
await page.click('[aria-label="Save"]');
|
||||||
}
|
}
|
||||||
|
@ -55,39 +55,50 @@ test.describe('Performance tests', () => {
|
|||||||
// Click text=OK
|
// Click text=OK
|
||||||
await page.locator('button:has-text("OK")').click();
|
await page.locator('button:has-text("OK")').click();
|
||||||
|
|
||||||
await expect(page.locator('a:has-text("Performance Display Layout Display Layout")')).toBeVisible();
|
await expect(
|
||||||
|
page.locator('a:has-text("Performance Display Layout Display Layout")')
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
//Create a Chrome Performance Timeline trace to store as a test artifact
|
//Create a Chrome Performance Timeline trace to store as a test artifact
|
||||||
console.log("\n==== Devtools: startTracing ====\n");
|
console.log('\n==== Devtools: startTracing ====\n');
|
||||||
await browser.startTracing(page, {
|
await browser.startTracing(page, {
|
||||||
path: `${testInfo.outputPath()}-trace.json`,
|
path: `${testInfo.outputPath()}-trace.json`,
|
||||||
screenshots: true
|
screenshots: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.afterEach(async ({ page, browser}) => {
|
test.afterEach(async ({ page, browser }) => {
|
||||||
console.log("\n==== Devtools: stopTracing ====\n");
|
console.log('\n==== Devtools: stopTracing ====\n');
|
||||||
await browser.stopTracing();
|
await browser.stopTracing();
|
||||||
|
|
||||||
/* Measurement Section
|
/* Measurement Section
|
||||||
/ The following section includes a block of performance measurements.
|
/ The following section includes a block of performance measurements.
|
||||||
*/
|
*/
|
||||||
//Get time difference between viewlarge actionability and evaluate time
|
//Get time difference between viewlarge actionability and evaluate time
|
||||||
await page.evaluate(() => (window.performance.measure("machine-time-difference", "viewlarge.start", "viewLarge.start.test")));
|
await page.evaluate(() =>
|
||||||
|
window.performance.measure(
|
||||||
|
'machine-time-difference',
|
||||||
|
'viewlarge.start',
|
||||||
|
'viewLarge.start.test'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
//Get StartTime
|
//Get StartTime
|
||||||
const startTime = await page.evaluate(() => window.performance.timing.navigationStart);
|
const startTime = await page.evaluate(() => window.performance.timing.navigationStart);
|
||||||
console.log('window.performance.timing.navigationStart', startTime);
|
console.log('window.performance.timing.navigationStart', startTime);
|
||||||
|
|
||||||
//Get All Performance Marks
|
//Get All Performance Marks
|
||||||
const getAllMarksJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType("mark")));
|
const getAllMarksJson = await page.evaluate(() =>
|
||||||
|
JSON.stringify(window.performance.getEntriesByType('mark'))
|
||||||
|
);
|
||||||
const getAllMarks = JSON.parse(getAllMarksJson);
|
const getAllMarks = JSON.parse(getAllMarksJson);
|
||||||
console.log('window.performance.getEntriesByType("mark")', getAllMarks);
|
console.log('window.performance.getEntriesByType("mark")', getAllMarks);
|
||||||
|
|
||||||
//Get All Performance Measures
|
//Get All Performance Measures
|
||||||
const getAllMeasuresJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType("measure")));
|
const getAllMeasuresJson = await page.evaluate(() =>
|
||||||
|
JSON.stringify(window.performance.getEntriesByType('measure'))
|
||||||
|
);
|
||||||
const getAllMeasures = JSON.parse(getAllMeasuresJson);
|
const getAllMeasures = JSON.parse(getAllMeasuresJson);
|
||||||
console.log('window.performance.getEntriesByType("measure")', getAllMeasures);
|
console.log('window.performance.getEntriesByType("measure")', getAllMeasures);
|
||||||
|
|
||||||
});
|
});
|
||||||
/* The following test will navigate to a previously created Performance Display Layout and measure the
|
/* The following test will navigate to a previously created Performance Display Layout and measure the
|
||||||
/ following metrics:
|
/ following metrics:
|
||||||
@ -104,48 +115,53 @@ test.describe('Performance tests', () => {
|
|||||||
|
|
||||||
// Search Available after Launch
|
// Search Available after Launch
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.evaluate(() => window.performance.mark("search-available"));
|
await page.evaluate(() => window.performance.mark('search-available'));
|
||||||
// Fill Search input
|
// Fill Search input
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Performance Display Layout');
|
await page
|
||||||
await page.evaluate(() => window.performance.mark("search-entered"));
|
.locator('[aria-label="OpenMCT Search"] input[type="search"]')
|
||||||
|
.fill('Performance Display Layout');
|
||||||
|
await page.evaluate(() => window.performance.mark('search-entered'));
|
||||||
//Search Result Appears and is clicked
|
//Search Result Appears and is clicked
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('a:has-text("Performance Display Layout")').first().click(),
|
page.locator('a:has-text("Performance Display Layout")').first().click(),
|
||||||
page.evaluate(() => window.performance.mark("click-search-result"))
|
page.evaluate(() => window.performance.mark('click-search-result'))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//Time to Example Imagery Frame loads within Display Layout
|
//Time to Example Imagery Frame loads within Display Layout
|
||||||
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' });
|
||||||
//Time to Example Imagery object loads
|
//Time to Example Imagery object loads
|
||||||
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' });
|
||||||
|
|
||||||
//Get background-image url from background-image css prop
|
//Get background-image url from background-image css prop
|
||||||
const backgroundImage = await page.locator('.c-imagery__main-image__background-image');
|
const backgroundImage = await page.locator('.c-imagery__main-image__background-image');
|
||||||
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
||||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
return window
|
||||||
|
.getComputedStyle(el)
|
||||||
|
.getPropertyValue('background-image')
|
||||||
|
.match(/url\(([^)]+)\)/)[1];
|
||||||
});
|
});
|
||||||
backgroundImageUrl = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
backgroundImageUrl = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
||||||
console.log('backgroundImageurl ' + backgroundImageUrl);
|
console.log('backgroundImageurl ' + backgroundImageUrl);
|
||||||
|
|
||||||
//Get ResourceTiming of background-image jpg
|
//Get ResourceTiming of background-image jpg
|
||||||
const resourceTimingJson = await page.evaluate((bgImageUrl) =>
|
const resourceTimingJson = await page.evaluate(
|
||||||
JSON.stringify(window.performance.getEntriesByName(bgImageUrl).pop()),
|
(bgImageUrl) => JSON.stringify(window.performance.getEntriesByName(bgImageUrl).pop()),
|
||||||
backgroundImageUrl
|
backgroundImageUrl
|
||||||
);
|
);
|
||||||
console.log('resourceTimingJson ' + resourceTimingJson);
|
console.log('resourceTimingJson ' + resourceTimingJson);
|
||||||
|
|
||||||
//Open Large view
|
//Open Large view
|
||||||
await page.locator('button:has-text("Large View")').click(); //This action includes the performance.mark named 'viewLarge.start'
|
await page.locator('button:has-text("Large View")').click(); //This action includes the performance.mark named 'viewLarge.start'
|
||||||
await page.evaluate(() => window.performance.mark("viewLarge.start.test")); //This is a mark only to compare evaluate timing
|
await page.evaluate(() => window.performance.mark('viewLarge.start.test')); //This is a mark only to compare evaluate timing
|
||||||
|
|
||||||
//Time to Imagery Rendered in Large Frame
|
//Time to Imagery Rendered in Large Frame
|
||||||
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("background-image-frame"));
|
await page.evaluate(() => window.performance.mark('background-image-frame'));
|
||||||
|
|
||||||
//Time to Example Imagery object loads
|
//Time to Example Imagery object loads
|
||||||
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("background-image-visible"));
|
await page.evaluate(() => window.performance.mark('background-image-visible'));
|
||||||
|
|
||||||
// Get Current number of images in thumbstrip
|
// Get Current number of images in thumbstrip
|
||||||
await page.waitForSelector('.c-imagery__thumb');
|
await page.waitForSelector('.c-imagery__thumb');
|
||||||
@ -158,20 +174,17 @@ test.describe('Performance tests', () => {
|
|||||||
JSON.stringify(window.performance.getEntriesByType('resource'))
|
JSON.stringify(window.performance.getEntriesByType('resource'))
|
||||||
);
|
);
|
||||||
const resourceTiming = JSON.parse(resourceTimingJson2);
|
const resourceTiming = JSON.parse(resourceTimingJson2);
|
||||||
const jpgResourceTiming = resourceTiming.find((element) =>
|
const jpgResourceTiming = resourceTiming.find((element) => element.name.includes('.jpg'));
|
||||||
element.name.includes('.jpg')
|
|
||||||
);
|
|
||||||
console.log('jpgResourceTiming ' + JSON.stringify(jpgResourceTiming));
|
console.log('jpgResourceTiming ' + JSON.stringify(jpgResourceTiming));
|
||||||
|
|
||||||
// Click Close Icon
|
// Click Close Icon
|
||||||
await page.locator('[aria-label="Close"]').click();
|
await page.locator('[aria-label="Close"]').click();
|
||||||
await page.evaluate(() => window.performance.mark("view-large-close-button"));
|
await page.evaluate(() => window.performance.mark('view-large-close-button'));
|
||||||
|
|
||||||
//await client.send('HeapProfiler.enable');
|
//await client.send('HeapProfiler.enable');
|
||||||
await client.send('HeapProfiler.collectGarbage');
|
await client.send('HeapProfiler.collectGarbage');
|
||||||
|
|
||||||
let performanceMetrics = await client.send('Performance.getMetrics');
|
let performanceMetrics = await client.send('Performance.getMetrics');
|
||||||
console.log(performanceMetrics.metrics);
|
console.log(performanceMetrics.metrics);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -56,17 +56,20 @@ test.describe.skip('Memory Performance tests', () => {
|
|||||||
// Click text=OK
|
// Click text=OK
|
||||||
await page.locator('text=OK').click();
|
await page.locator('text=OK').click();
|
||||||
|
|
||||||
await expect(page.locator('a:has-text("Performance Display Layout Display Layout")')).toBeVisible();
|
await expect(
|
||||||
|
page.locator('a:has-text("Performance Display Layout Display Layout")')
|
||||||
|
).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Embedded View Large for Imagery is performant in Fixed Time', async ({ page, browser }) => {
|
test('Embedded View Large for Imagery is performant in Fixed Time', async ({ page, browser }) => {
|
||||||
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
await page.goto('./', {waitUntil: 'networkidle'});
|
|
||||||
|
|
||||||
// To to Search Available after Launch
|
// To to Search Available after Launch
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
// Fill Search input
|
// Fill Search input
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Performance Display Layout');
|
await page
|
||||||
|
.locator('[aria-label="OpenMCT Search"] input[type="search"]')
|
||||||
|
.fill('Performance Display Layout');
|
||||||
//Search Result Appears and is clicked
|
//Search Result Appears and is clicked
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
@ -74,9 +77,9 @@ test.describe.skip('Memory Performance tests', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
//Time to Example Imagery Frame loads within Display Layout
|
//Time to Example Imagery Frame loads within Display Layout
|
||||||
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' });
|
||||||
//Time to Example Imagery object loads
|
//Time to Example Imagery object loads
|
||||||
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' });
|
||||||
|
|
||||||
const client = await page.context().newCDPSession(page);
|
const client = await page.context().newCDPSession(page);
|
||||||
await client.send('HeapProfiler.enable');
|
await client.send('HeapProfiler.enable');
|
||||||
@ -94,18 +97,18 @@ test.describe.skip('Memory Performance tests', () => {
|
|||||||
await client.send('HeapProfiler.takeHeapSnapshot');
|
await client.send('HeapProfiler.takeHeapSnapshot');
|
||||||
|
|
||||||
//Time to Imagery Rendered in Large Frame
|
//Time to Imagery Rendered in Large Frame
|
||||||
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' });
|
||||||
|
|
||||||
//Time to Example Imagery object loads
|
//Time to Example Imagery object loads
|
||||||
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' });
|
||||||
|
|
||||||
// Click Close Icon
|
// Click Close Icon
|
||||||
await page.locator('.c-click-icon').click();
|
await page.locator('.c-click-icon').click();
|
||||||
|
|
||||||
//Time to Example Imagery Frame loads within Display Layout
|
//Time to Example Imagery Frame loads within Display Layout
|
||||||
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__bg', { state: 'visible' });
|
||||||
//Time to Example Imagery object loads
|
//Time to Example Imagery object loads
|
||||||
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible'});
|
await page.waitForSelector('.c-imagery__main-image__background-image', { state: 'visible' });
|
||||||
|
|
||||||
await client.send('HeapProfiler.collectGarbage');
|
await client.send('HeapProfiler.collectGarbage');
|
||||||
//await client.send('Performance.enable');
|
//await client.send('Performance.enable');
|
||||||
@ -114,6 +117,5 @@ test.describe.skip('Memory Performance tests', () => {
|
|||||||
console.log(performanceMetricsAfter.metrics);
|
console.log(performanceMetricsAfter.metrics);
|
||||||
|
|
||||||
//await client.send('Performance.disable');
|
//await client.send('Performance.disable');
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -57,14 +57,14 @@ test.describe('Performance tests', () => {
|
|||||||
await expect(page.locator('a:has-text("Performance Notebook")')).toBeVisible();
|
await expect(page.locator('a:has-text("Performance Notebook")')).toBeVisible();
|
||||||
|
|
||||||
//Create a Chrome Performance Timeline trace to store as a test artifact
|
//Create a Chrome Performance Timeline trace to store as a test artifact
|
||||||
console.log("\n==== Devtools: startTracing ====\n");
|
console.log('\n==== Devtools: startTracing ====\n');
|
||||||
await browser.startTracing(page, {
|
await browser.startTracing(page, {
|
||||||
path: `${testInfo.outputPath()}-trace.json`,
|
path: `${testInfo.outputPath()}-trace.json`,
|
||||||
screenshots: true
|
screenshots: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.afterEach(async ({ page, browser}) => {
|
test.afterEach(async ({ page, browser }) => {
|
||||||
console.log("\n==== Devtools: stopTracing ====\n");
|
console.log('\n==== Devtools: stopTracing ====\n');
|
||||||
await browser.stopTracing();
|
await browser.stopTracing();
|
||||||
|
|
||||||
/* Measurement Section
|
/* Measurement Section
|
||||||
@ -74,15 +74,18 @@ test.describe('Performance tests', () => {
|
|||||||
console.log('window.performance.timing.navigationStart', startTime);
|
console.log('window.performance.timing.navigationStart', startTime);
|
||||||
|
|
||||||
//Get All Performance Marks
|
//Get All Performance Marks
|
||||||
const getAllMarksJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType("mark")));
|
const getAllMarksJson = await page.evaluate(() =>
|
||||||
|
JSON.stringify(window.performance.getEntriesByType('mark'))
|
||||||
|
);
|
||||||
const getAllMarks = JSON.parse(getAllMarksJson);
|
const getAllMarks = JSON.parse(getAllMarksJson);
|
||||||
console.log('window.performance.getEntriesByType("mark")', getAllMarks);
|
console.log('window.performance.getEntriesByType("mark")', getAllMarks);
|
||||||
|
|
||||||
//Get All Performance Measures
|
//Get All Performance Measures
|
||||||
const getAllMeasuresJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType("measure")));
|
const getAllMeasuresJson = await page.evaluate(() =>
|
||||||
|
JSON.stringify(window.performance.getEntriesByType('measure'))
|
||||||
|
);
|
||||||
const getAllMeasures = JSON.parse(getAllMeasuresJson);
|
const getAllMeasures = JSON.parse(getAllMeasuresJson);
|
||||||
console.log('window.performance.getEntriesByType("measure")', getAllMeasures);
|
console.log('window.performance.getEntriesByType("measure")', getAllMeasures);
|
||||||
|
|
||||||
});
|
});
|
||||||
/* The following test will navigate to a previously created Performance Display Layout and measure the
|
/* The following test will navigate to a previously created Performance Display Layout and measure the
|
||||||
/ following metrics:
|
/ following metrics:
|
||||||
@ -99,56 +102,60 @@ test.describe('Performance tests', () => {
|
|||||||
|
|
||||||
// To to Search Available after Launch
|
// To to Search Available after Launch
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
|
||||||
await page.evaluate(() => window.performance.mark("search-available"));
|
await page.evaluate(() => window.performance.mark('search-available'));
|
||||||
// Fill Search input
|
// Fill Search input
|
||||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('Performance Notebook');
|
await page
|
||||||
await page.evaluate(() => window.performance.mark("search-entered"));
|
.locator('[aria-label="OpenMCT Search"] input[type="search"]')
|
||||||
|
.fill('Performance Notebook');
|
||||||
|
await page.evaluate(() => window.performance.mark('search-entered'));
|
||||||
//Search Result Appears and is clicked
|
//Search Result Appears and is clicked
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
page.locator('a:has-text("Performance Notebook")').first().click(),
|
page.locator('a:has-text("Performance Notebook")').first().click(),
|
||||||
page.evaluate(() => window.performance.mark("click-search-result"))
|
page.evaluate(() => window.performance.mark('click-search-result'))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await page.waitForSelector('.c-tree__item c-tree-and-search__loading loading', {state: 'hidden'});
|
await page.waitForSelector('.c-tree__item c-tree-and-search__loading loading', {
|
||||||
await page.evaluate(() => window.performance.mark("search-spinner-gone"));
|
state: 'hidden'
|
||||||
|
});
|
||||||
|
await page.evaluate(() => window.performance.mark('search-spinner-gone'));
|
||||||
|
|
||||||
await page.waitForSelector('.l-browse-bar__object-name', { state: 'visible'});
|
await page.waitForSelector('.l-browse-bar__object-name', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("object-title-appears"));
|
await page.evaluate(() => window.performance.mark('object-title-appears'));
|
||||||
|
|
||||||
await page.waitForSelector('.c-notebook__entry >> nth=0', { state: 'visible'});
|
await page.waitForSelector('.c-notebook__entry >> nth=0', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("notebook-entry-appears"));
|
await page.evaluate(() => window.performance.mark('notebook-entry-appears'));
|
||||||
|
|
||||||
// Click Add new Notebook Entry
|
// Click Add new Notebook Entry
|
||||||
await page.locator('.c-notebook__drag-area').click();
|
await page.locator('.c-notebook__drag-area').click();
|
||||||
await page.evaluate(() => window.performance.mark("new-notebook-entry-created"));
|
await page.evaluate(() => window.performance.mark('new-notebook-entry-created'));
|
||||||
|
|
||||||
// Enter Notebook Entry text
|
// Enter Notebook Entry text
|
||||||
await page.locator('div.c-ne__text').last().fill('New Entry');
|
await page.locator('div.c-ne__text').last().fill('New Entry');
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
await page.evaluate(() => window.performance.mark("new-notebook-entry-filled"));
|
await page.evaluate(() => window.performance.mark('new-notebook-entry-filled'));
|
||||||
|
|
||||||
//Individual Notebook Entry Search
|
//Individual Notebook Entry Search
|
||||||
await page.evaluate(() => window.performance.mark("notebook-search-start"));
|
await page.evaluate(() => window.performance.mark('notebook-search-start'));
|
||||||
await page.locator('.c-notebook__search >> input').fill('Existing Entry');
|
await page.locator('.c-notebook__search >> input').fill('Existing Entry');
|
||||||
await page.evaluate(() => window.performance.mark("notebook-search-filled"));
|
await page.evaluate(() => window.performance.mark('notebook-search-filled'));
|
||||||
await page.waitForSelector('text=Search Results (3)', { state: 'visible'});
|
await page.waitForSelector('text=Search Results (3)', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("notebook-search-processed"));
|
await page.evaluate(() => window.performance.mark('notebook-search-processed'));
|
||||||
await page.waitForSelector('.c-notebook__entry >> nth=2', { state: 'visible'});
|
await page.waitForSelector('.c-notebook__entry >> nth=2', { state: 'visible' });
|
||||||
await page.evaluate(() => window.performance.mark("notebook-search-processed"));
|
await page.evaluate(() => window.performance.mark('notebook-search-processed'));
|
||||||
|
|
||||||
//Clear Search
|
//Clear Search
|
||||||
await page.locator('.c-search.c-notebook__search .c-search__input').hover();
|
await page.locator('.c-search.c-notebook__search .c-search__input').hover();
|
||||||
await page.locator('.c-search.c-notebook__search .c-search__clear-input').click();
|
await page.locator('.c-search.c-notebook__search .c-search__clear-input').click();
|
||||||
await page.evaluate(() => window.performance.mark("notebook-search-processed"));
|
await page.evaluate(() => window.performance.mark('notebook-search-processed'));
|
||||||
|
|
||||||
// Hover on Last
|
// Hover on Last
|
||||||
await page.evaluate(() => window.performance.mark("new-notebook-entry-delete"));
|
await page.evaluate(() => window.performance.mark('new-notebook-entry-delete'));
|
||||||
await page.locator('div.c-ne__time-and-content').last().hover();
|
await page.locator('div.c-ne__time-and-content').last().hover();
|
||||||
await page.locator('button[title="Delete this entry"]').last().click();
|
await page.locator('button[title="Delete this entry"]').last().click();
|
||||||
await page.locator('button:has-text("Ok")').click();
|
await page.locator('button:has-text("Ok")').click();
|
||||||
await page.waitForSelector('.c-notebook__entry >> nth=3', { state: 'detached'});
|
await page.waitForSelector('.c-notebook__entry >> nth=3', { state: 'detached' });
|
||||||
await page.evaluate(() => window.performance.mark("new-notebook-entry-deleted"));
|
await page.evaluate(() => window.performance.mark('new-notebook-entry-deleted'));
|
||||||
|
|
||||||
//await client.send('HeapProfiler.enable');
|
//await client.send('HeapProfiler.enable');
|
||||||
await client.send('HeapProfiler.collectGarbage');
|
await client.send('HeapProfiler.collectGarbage');
|
||||||
|
@ -48,7 +48,9 @@ test.describe('Visual - addInit', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Restricted Notebook is visually correct @addInit @unstable', async ({ page, theme }) => {
|
test('Restricted Notebook is visually correct @addInit @unstable', async ({ page, theme }) => {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../helper', './addInitRestrictedNotebook.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../helper', './addInitRestrictedNotebook.js')
|
||||||
|
});
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./#/browse/mine?hideTree=true', { waitUntil: 'networkidle' });
|
await page.goto('./#/browse/mine?hideTree=true', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
@ -56,6 +58,5 @@ test.describe('Visual - addInit', () => {
|
|||||||
|
|
||||||
// Take a snapshot of the newly created CUSTOM_NAME notebook
|
// Take a snapshot of the newly created CUSTOM_NAME notebook
|
||||||
await percySnapshot(page, `Restricted Notebook with CUSTOM_NAME (theme: '${theme}')`);
|
await percySnapshot(page, `Restricted Notebook with CUSTOM_NAME (theme: '${theme}')`);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,18 +32,18 @@ test.describe('Visual - Tree Pane', () => {
|
|||||||
|
|
||||||
const foo = await createDomainObjectWithDefaults(page, {
|
const foo = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Folder',
|
type: 'Folder',
|
||||||
name: "Foo Folder"
|
name: 'Foo Folder'
|
||||||
});
|
});
|
||||||
|
|
||||||
const bar = await createDomainObjectWithDefaults(page, {
|
const bar = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Folder',
|
type: 'Folder',
|
||||||
name: "Bar Folder",
|
name: 'Bar Folder',
|
||||||
parent: foo.uuid
|
parent: foo.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
const baz = await createDomainObjectWithDefaults(page, {
|
const baz = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Folder',
|
type: 'Folder',
|
||||||
name: "Baz Folder",
|
name: 'Baz Folder',
|
||||||
parent: bar.uuid
|
parent: bar.uuid
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ test.describe('Visual - Controlled Clock @localStorage', () => {
|
|||||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
|
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
|
||||||
|
|
||||||
//Wait for canvas to be rendered and stop animating
|
//Wait for canvas to be rendered and stop animating
|
||||||
await page.locator('canvas >> nth=1').hover({trial: true});
|
await page.locator('canvas >> nth=1').hover({ trial: true });
|
||||||
|
|
||||||
//Take snapshot of Sine Wave Generator within Overlay Plot
|
//Take snapshot of Sine Wave Generator within Overlay Plot
|
||||||
await percySnapshot(page, `SineWaveInOverlayPlot (theme: '${theme}')`);
|
await percySnapshot(page, `SineWaveInOverlayPlot (theme: '${theme}')`);
|
||||||
|
@ -61,14 +61,17 @@ test.describe('Visual - Default', () => {
|
|||||||
// Modify the Build information in 'about' to be consistent run-over-run
|
// Modify the Build information in 'about' to be consistent run-over-run
|
||||||
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
const versionInformationLocator = page.locator('ul.t-info.l-info.s-info').first();
|
||||||
await expect(versionInformationLocator).toBeEnabled();
|
await expect(versionInformationLocator).toBeEnabled();
|
||||||
await versionInformationLocator.evaluate(node => node.innerHTML = '<li>Version: visual-snapshot</li> <li>Build Date: Mon Nov 15 2021 08:07:51 GMT-0800 (Pacific Standard Time)</li> <li>Revision: 93049cdbc6c047697ca204893db9603b864b8c9f</li> <li>Branch: master</li>');
|
await versionInformationLocator.evaluate(
|
||||||
|
(node) =>
|
||||||
|
(node.innerHTML =
|
||||||
|
'<li>Version: visual-snapshot</li> <li>Build Date: Mon Nov 15 2021 08:07:51 GMT-0800 (Pacific Standard Time)</li> <li>Revision: 93049cdbc6c047697ca204893db9603b864b8c9f</li> <li>Branch: master</li>')
|
||||||
|
);
|
||||||
|
|
||||||
// Take a snapshot of the About modal
|
// Take a snapshot of the About modal
|
||||||
await percySnapshot(page, `About (theme: '${theme}')`);
|
await percySnapshot(page, `About (theme: '${theme}')`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Visual - Default Condition Set @unstable', async ({ page, theme }) => {
|
test('Visual - Default Condition Set @unstable', async ({ page, theme }) => {
|
||||||
|
|
||||||
await createDomainObjectWithDefaults(page, { type: 'Condition Set' });
|
await createDomainObjectWithDefaults(page, { type: 'Condition Set' });
|
||||||
|
|
||||||
// Take a snapshot of the newly created Condition Set object
|
// Take a snapshot of the newly created Condition Set object
|
||||||
@ -102,17 +105,17 @@ test.describe('Visual - Default', () => {
|
|||||||
// verify no error msg
|
// verify no error msg
|
||||||
await percySnapshot(page, `Default Time conductor (theme: '${theme}')`);
|
await percySnapshot(page, `Default Time conductor (theme: '${theme}')`);
|
||||||
|
|
||||||
startDate = (year + 1) + startDate.substring(4);
|
startDate = year + 1 + startDate.substring(4);
|
||||||
await page.locator('input[type="text"]').first().fill(startDate.toString());
|
await page.locator('input[type="text"]').first().fill(startDate.toString());
|
||||||
await page.locator('input[type="text"]').nth(1).click();
|
await page.locator('input[type="text"]').nth(1).click();
|
||||||
|
|
||||||
// verify error msg for start time (unable to capture snapshot of popup)
|
// verify error msg for start time (unable to capture snapshot of popup)
|
||||||
await percySnapshot(page, `Start time error (theme: '${theme}')`);
|
await percySnapshot(page, `Start time error (theme: '${theme}')`);
|
||||||
|
|
||||||
startDate = (year - 1) + startDate.substring(4);
|
startDate = year - 1 + startDate.substring(4);
|
||||||
await page.locator('input[type="text"]').first().fill(startDate.toString());
|
await page.locator('input[type="text"]').first().fill(startDate.toString());
|
||||||
|
|
||||||
endDate = (year - 2) + endDate.substring(4);
|
endDate = year - 2 + endDate.substring(4);
|
||||||
await page.locator('input[type="text"]').nth(1).fill(endDate.toString());
|
await page.locator('input[type="text"]').nth(1).fill(endDate.toString());
|
||||||
|
|
||||||
await page.locator('input[type="text"]').first().click();
|
await page.locator('input[type="text"]').first().click();
|
||||||
@ -145,7 +148,7 @@ test.describe('Visual - Default', () => {
|
|||||||
|
|
||||||
//Wait until Save Banner is gone
|
//Wait until Save Banner is gone
|
||||||
await page.locator('.c-message-banner__close-button').click();
|
await page.locator('.c-message-banner__close-button').click();
|
||||||
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
|
await page.waitForSelector('.c-message-banner__message', { state: 'detached' });
|
||||||
await percySnapshot(page, `Banner message gone (theme: '${theme}')`);
|
await percySnapshot(page, `Banner message gone (theme: '${theme}')`);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -156,7 +159,6 @@ test.describe('Visual - Default', () => {
|
|||||||
//Hover on Display Layout option.
|
//Hover on Display Layout option.
|
||||||
await page.locator('text=Display Layout').hover();
|
await page.locator('text=Display Layout').hover();
|
||||||
await percySnapshot(page, `Display Layout Create Menu (theme: '${theme}')`);
|
await percySnapshot(page, `Display Layout Create Menu (theme: '${theme}')`);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Visual - Default Gauge is correct @unstable', async ({ page, theme }) => {
|
test('Visual - Default Gauge is correct @unstable', async ({ page, theme }) => {
|
||||||
|
@ -27,9 +27,10 @@ const percySnapshot = require('@percy/playwright');
|
|||||||
const utils = require('../../helper/faultUtils');
|
const utils = require('../../helper/faultUtils');
|
||||||
|
|
||||||
test.describe('The Fault Management Plugin Visual Test', () => {
|
test.describe('The Fault Management Plugin Visual Test', () => {
|
||||||
|
|
||||||
test('icon test', async ({ page, theme }) => {
|
test('icon test', async ({ page, theme }) => {
|
||||||
await page.addInitScript({ path: path.join(__dirname, '../../helper/', 'addInitFaultManagementPlugin.js') });
|
await page.addInitScript({
|
||||||
|
path: path.join(__dirname, '../../helper/', 'addInitFaultManagementPlugin.js')
|
||||||
|
});
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
await percySnapshot(page, `Fault Management icon appears in tree (theme: '${theme}')`);
|
await percySnapshot(page, `Fault Management icon appears in tree (theme: '${theme}')`);
|
||||||
@ -43,7 +44,10 @@ test.describe('The Fault Management Plugin Visual Test', () => {
|
|||||||
await utils.acknowledgeFault(page, 1);
|
await utils.acknowledgeFault(page, 1);
|
||||||
await utils.changeViewTo(page, 'acknowledged');
|
await utils.changeViewTo(page, 'acknowledged');
|
||||||
|
|
||||||
await percySnapshot(page, `Acknowledged faults, have a checkmark on the fault icon and appear in the acknowldeged view (theme: '${theme}')`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`Acknowledged faults, have a checkmark on the fault icon and appear in the acknowldeged view (theme: '${theme}')`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shelved faults', async ({ page, theme }) => {
|
test('shelved faults', async ({ page, theme }) => {
|
||||||
@ -56,7 +60,10 @@ test.describe('The Fault Management Plugin Visual Test', () => {
|
|||||||
|
|
||||||
await utils.openFaultRowMenu(page, 1);
|
await utils.openFaultRowMenu(page, 1);
|
||||||
|
|
||||||
await percySnapshot(page, `Shelved faults have a 3-dot menu with Unshelve option enabled (theme: '${theme}')`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`Shelved faults have a 3-dot menu with Unshelve option enabled (theme: '${theme}')`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('3-dot menu for fault', async ({ page, theme }) => {
|
test('3-dot menu for fault', async ({ page, theme }) => {
|
||||||
@ -64,7 +71,10 @@ test.describe('The Fault Management Plugin Visual Test', () => {
|
|||||||
|
|
||||||
await utils.openFaultRowMenu(page, 1);
|
await utils.openFaultRowMenu(page, 1);
|
||||||
|
|
||||||
await percySnapshot(page, `Faults have a 3-dot menu with Acknowledge, Shelve and Unshelve (Unshelve is disabled) options (theme: '${theme}')`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`Faults have a 3-dot menu with Acknowledge, Shelve and Unshelve (Unshelve is disabled) options (theme: '${theme}')`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ability to acknowledge or shelve', async ({ page, theme }) => {
|
test('ability to acknowledge or shelve', async ({ page, theme }) => {
|
||||||
@ -72,6 +82,9 @@ test.describe('The Fault Management Plugin Visual Test', () => {
|
|||||||
|
|
||||||
await utils.selectFaultItem(page, 1);
|
await utils.selectFaultItem(page, 1);
|
||||||
|
|
||||||
await percySnapshot(page, `Selected faults highlight the ability to Acknowledge or Shelve above the fault list (theme: '${theme}')`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`Selected faults highlight the ability to Acknowledge or Shelve above the fault list (theme: '${theme}')`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -54,7 +54,6 @@ test.describe('Visual - LAD Table', () => {
|
|||||||
await page.getByRole('button', { name: 'Save' }).click();
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
});
|
});
|
||||||
test('Toggled column widths behave accordingly', async ({ page, theme }) => {
|
test('Toggled column widths behave accordingly', async ({ page, theme }) => {
|
||||||
|
|
||||||
await page.goto(ladTable.url);
|
await page.goto(ladTable.url);
|
||||||
//Close panes for visual consistency
|
//Close panes for visual consistency
|
||||||
await page.getByTitle('Collapse Inspect Pane').click();
|
await page.getByTitle('Collapse Inspect Pane').click();
|
||||||
@ -62,13 +61,18 @@ test.describe('Visual - LAD Table', () => {
|
|||||||
|
|
||||||
await expect(page.locator('button[title="Expand Columns"]')).toBeVisible();
|
await expect(page.locator('button[title="Expand Columns"]')).toBeVisible();
|
||||||
|
|
||||||
await percySnapshot(page, `LAD Table w/ Sine Wave Generator columns autosized (theme: ${theme})`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`LAD Table w/ Sine Wave Generator columns autosized (theme: ${theme})`
|
||||||
|
);
|
||||||
|
|
||||||
await page.locator('button[title="Expand Columns"]').click();
|
await page.locator('button[title="Expand Columns"]').click();
|
||||||
|
|
||||||
await expect(page.locator('button[title="Autosize Columns"]')).toBeVisible();
|
await expect(page.locator('button[title="Autosize Columns"]')).toBeVisible();
|
||||||
|
|
||||||
await percySnapshot(page, `LAD Table w/ Sine Wave Generator columns expanded (theme: ${theme})`);
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
`LAD Table w/ Sine Wave Generator columns expanded (theme: ${theme})`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,12 +32,12 @@ test.describe('Visual - Notebook', () => {
|
|||||||
// Create Notebook
|
// Create Notebook
|
||||||
const notebook = await createDomainObjectWithDefaults(page, {
|
const notebook = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Notebook',
|
type: 'Notebook',
|
||||||
name: "Embed Test Notebook"
|
name: 'Embed Test Notebook'
|
||||||
});
|
});
|
||||||
// Create Overlay Plot
|
// Create Overlay Plot
|
||||||
await createDomainObjectWithDefaults(page, {
|
await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Overlay Plot',
|
type: 'Overlay Plot',
|
||||||
name: "Dropped Overlay Plot"
|
name: 'Dropped Overlay Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
await expandTreePaneItemByName(page, myItemsFolderName);
|
await expandTreePaneItemByName(page, myItemsFolderName);
|
||||||
@ -46,6 +46,5 @@ test.describe('Visual - Notebook', () => {
|
|||||||
await page.dragAndDrop('role=treeitem[name=/Dropped Overlay Plot/]', '.c-notebook__drag-area');
|
await page.dragAndDrop('role=treeitem[name=/Dropped Overlay Plot/]', '.c-notebook__drag-area');
|
||||||
|
|
||||||
await percySnapshot(page, `Notebook w/ dropped embed (theme: ${theme})`);
|
await percySnapshot(page, `Notebook w/ dropped embed (theme: ${theme})`);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -28,19 +28,24 @@ const { test, expect } = require('../../pluginFixtures');
|
|||||||
const percySnapshot = require('@percy/playwright');
|
const percySnapshot = require('@percy/playwright');
|
||||||
const { createDomainObjectWithDefaults } = require('../../appActions');
|
const { createDomainObjectWithDefaults } = require('../../appActions');
|
||||||
|
|
||||||
test.describe('Visual - Check Notification Info Banner of \'Save successful\'', () => {
|
test.describe("Visual - Check Notification Info Banner of 'Save successful'", () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Go to baseURL and Hide Tree
|
// Go to baseURL and Hide Tree
|
||||||
await page.goto('./', { waitUntil: 'networkidle' });
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Create a clock, click on \'Save successful\' banner and dismiss it', async ({ page, theme }) => {
|
test("Create a clock, click on 'Save successful' banner and dismiss it", async ({
|
||||||
|
page,
|
||||||
|
theme
|
||||||
|
}) => {
|
||||||
// Create a clock domain object
|
// Create a clock domain object
|
||||||
await createDomainObjectWithDefaults(page, { type: 'Clock' });
|
await createDomainObjectWithDefaults(page, { type: 'Clock' });
|
||||||
// Verify there is a button with aria-label="Review 1 Notification"
|
// Verify there is a button with aria-label="Review 1 Notification"
|
||||||
expect(await page.locator('button[aria-label="Review 1 Notification"]').isVisible()).toBe(true);
|
expect(await page.locator('button[aria-label="Review 1 Notification"]').isVisible()).toBe(true);
|
||||||
// Verify there is a button with aria-label="Clear all notifications"
|
// Verify there is a button with aria-label="Clear all notifications"
|
||||||
expect(await page.locator('button[aria-label="Clear all notifications"]').isVisible()).toBe(true);
|
expect(await page.locator('button[aria-label="Clear all notifications"]').isVisible()).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
// Click on the div with role="alert" that has "Save successful" text
|
// Click on the div with role="alert" that has "Save successful" text
|
||||||
await page.locator('div[role="alert"]:has-text("Save successful")').click();
|
await page.locator('div[role="alert"]:has-text("Save successful")').click();
|
||||||
// Verify there is a div with role="dialog"
|
// Verify there is a div with role="dialog"
|
||||||
|
@ -41,7 +41,10 @@ test.describe('Grand Search', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
//This needs to be rewritten to use a non clock or non display layout object
|
//This needs to be rewritten to use a non clock or non display layout object
|
||||||
test('Can search for objects, and subsequent search dropdown behaves properly @unstable', async ({ page, theme }) => {
|
test('Can search for objects, and subsequent search dropdown behaves properly @unstable', async ({
|
||||||
|
page,
|
||||||
|
theme
|
||||||
|
}) => {
|
||||||
// await createDomainObjectWithDefaults(page, 'Display Layout');
|
// await createDomainObjectWithDefaults(page, 'Display Layout');
|
||||||
// await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
// await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
||||||
// await page.locator('text=Save and Finish Editing').click();
|
// await page.locator('text=Save and Finish Editing').click();
|
||||||
@ -60,12 +63,18 @@ test.describe('Grand Search', () => {
|
|||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').click();
|
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').click();
|
||||||
await page.locator('[aria-label="Unnamed Clock clock result"] >> text=Unnamed Clock').click();
|
await page.locator('[aria-label="Unnamed Clock clock result"] >> text=Unnamed Clock').click();
|
||||||
await percySnapshot(page, 'Preview for clock should display when editing enabled and search item clicked');
|
await percySnapshot(
|
||||||
|
page,
|
||||||
|
'Preview for clock should display when editing enabled and search item clicked'
|
||||||
|
);
|
||||||
|
|
||||||
await page.locator('[aria-label="Close"]').click();
|
await page.locator('[aria-label="Close"]').click();
|
||||||
await percySnapshot(page, 'Search should still be showing after preview closed');
|
await percySnapshot(page, 'Search should still be showing after preview closed');
|
||||||
|
|
||||||
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
|
await page
|
||||||
|
.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button')
|
||||||
|
.nth(1)
|
||||||
|
.click();
|
||||||
|
|
||||||
await page.locator('text=Save and Finish Editing').click();
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
|
|
||||||
@ -73,12 +82,10 @@ test.describe('Grand Search', () => {
|
|||||||
|
|
||||||
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Cl');
|
await page.locator('[aria-label="OpenMCT Search"] [aria-label="Search Input"]').fill('Cl');
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([page.waitForNavigation(), page.locator('text=Unnamed Clock').click()]);
|
||||||
page.waitForNavigation(),
|
await percySnapshot(
|
||||||
page.locator('text=Unnamed Clock').click()
|
page,
|
||||||
]);
|
`Clicking on search results should navigate to them if not editing (theme: '${theme}')`
|
||||||
await percySnapshot(page, `Clicking on search results should navigate to them if not editing (theme: '${theme}')`);
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,25 +23,25 @@
|
|||||||
class EventMetadataProvider {
|
class EventMetadataProvider {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.METADATA_BY_TYPE = {
|
this.METADATA_BY_TYPE = {
|
||||||
'eventGenerator': {
|
eventGenerator: {
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: 'name',
|
||||||
name: "Name",
|
name: 'Name',
|
||||||
format: "string"
|
format: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "utc",
|
key: 'utc',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "message",
|
key: 'message',
|
||||||
name: "Message",
|
name: 'Message',
|
||||||
format: "string"
|
format: 'string'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -53,11 +53,7 @@ class EventMetadataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMetadata(domainObject) {
|
getMetadata(domainObject) {
|
||||||
return Object.assign(
|
return Object.assign({}, domainObject.telemetry, this.METADATA_BY_TYPE[domainObject.type]);
|
||||||
{},
|
|
||||||
domainObject.telemetry,
|
|
||||||
this.METADATA_BY_TYPE[domainObject.type]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ class EventTelemetryProvider {
|
|||||||
|
|
||||||
generateData(firstObservedTime, count, startTime, duration, name) {
|
generateData(firstObservedTime, count, startTime, duration, name) {
|
||||||
const millisecondsSinceStart = startTime - firstObservedTime;
|
const millisecondsSinceStart = startTime - firstObservedTime;
|
||||||
const utc = startTime + (count * duration);
|
const utc = startTime + count * duration;
|
||||||
const ind = count % messages.length;
|
const ind = count % messages.length;
|
||||||
const message = messages[ind] + " - [" + millisecondsSinceStart + "]";
|
const message = messages[ind] + ' - [' + millisecondsSinceStart + ']';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
@ -59,7 +59,13 @@ class EventTelemetryProvider {
|
|||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const datum = this.generateData(firstObservedTime, count, startTime, duration, domainObject.name);
|
const datum = this.generateData(
|
||||||
|
firstObservedTime,
|
||||||
|
count,
|
||||||
|
startTime,
|
||||||
|
duration,
|
||||||
|
domainObject.name
|
||||||
|
);
|
||||||
count += 1;
|
count += 1;
|
||||||
callback(datum);
|
callback(datum);
|
||||||
}, duration);
|
}, duration);
|
||||||
@ -84,7 +90,9 @@ class EventTelemetryProvider {
|
|||||||
|
|
||||||
while (start <= end && data.length < size) {
|
while (start <= end && data.length < size) {
|
||||||
const startTime = options.start + count;
|
const startTime = options.start + count;
|
||||||
data.push(this.generateData(firstObservedTime, count, startTime, duration, domainObject.name));
|
data.push(
|
||||||
|
this.generateData(firstObservedTime, count, startTime, duration, domainObject.name)
|
||||||
|
);
|
||||||
start += duration;
|
start += duration;
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,11 @@ import EventMetadataProvider from './EventMetadataProvider';
|
|||||||
|
|
||||||
export default function EventGeneratorPlugin(options) {
|
export default function EventGeneratorPlugin(options) {
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
openmct.types.addType("eventGenerator", {
|
openmct.types.addType('eventGenerator', {
|
||||||
name: "Event Message Generator",
|
name: 'Event Message Generator',
|
||||||
description: "For development use. Creates sample event message data that mimics a live data stream.",
|
description:
|
||||||
cssClass: "icon-generator-events",
|
'For development use. Creates sample event message data that mimics a live data stream.',
|
||||||
|
cssClass: 'icon-generator-events',
|
||||||
creatable: true,
|
creatable: true,
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
object.telemetry = {
|
object.telemetry = {
|
||||||
@ -37,6 +38,5 @@ export default function EventGeneratorPlugin(options) {
|
|||||||
});
|
});
|
||||||
openmct.telemetry.addProvider(new EventTelmetryProvider());
|
openmct.telemetry.addProvider(new EventTelmetryProvider());
|
||||||
openmct.telemetry.addProvider(new EventMetadataProvider());
|
openmct.telemetry.addProvider(new EventMetadataProvider());
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import EventMessageGeneratorPlugin from './plugin.js';
|
import EventMessageGeneratorPlugin from './plugin.js';
|
||||||
import {
|
import { createOpenMct, resetApplicationState } from '../../src/utils/testing';
|
||||||
createOpenMct,
|
|
||||||
resetApplicationState
|
|
||||||
} from '../../src/utils/testing';
|
|
||||||
|
|
||||||
describe('the plugin', () => {
|
describe('the plugin', () => {
|
||||||
let openmct;
|
let openmct;
|
||||||
@ -52,7 +49,7 @@ describe('the plugin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('the plugin', () => {
|
describe('the plugin', () => {
|
||||||
it("supports subscription", (done) => {
|
it('supports subscription', (done) => {
|
||||||
const unsubscribe = openmct.telemetry.subscribe(mockDomainObject, (telemetry) => {
|
const unsubscribe = openmct.telemetry.subscribe(mockDomainObject, (telemetry) => {
|
||||||
expect(telemetry).not.toEqual(null);
|
expect(telemetry).not.toEqual(null);
|
||||||
expect(telemetry.message).toContain('CC: Eagle, Houston');
|
expect(telemetry.message).toContain('CC: Eagle, Houston');
|
||||||
@ -62,12 +59,12 @@ describe('the plugin', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("supports requests without start/end defined", async () => {
|
it('supports requests without start/end defined', async () => {
|
||||||
const telemetry = await openmct.telemetry.request(mockDomainObject);
|
const telemetry = await openmct.telemetry.request(mockDomainObject);
|
||||||
expect(telemetry[0].message).toContain('CC: Eagle, Houston');
|
expect(telemetry[0].message).toContain('CC: Eagle, Houston');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("supports requests with arbitrary start time in the past", async () => {
|
it('supports requests with arbitrary start time in the past', async () => {
|
||||||
mockDomainObject.options.start = 100000000000; // Mar 03 1973
|
mockDomainObject.options.start = 100000000000; // Mar 03 1973
|
||||||
const telemetry = await openmct.telemetry.request(mockDomainObject);
|
const telemetry = await openmct.telemetry.request(mockDomainObject);
|
||||||
expect(telemetry[0].message).toContain('CC: Eagle, Houston');
|
expect(telemetry[0].message).toContain('CC: Eagle, Houston');
|
||||||
|
@ -37,7 +37,7 @@ export default function exampleTagsPlugin(options) {
|
|||||||
openmct.annotation.setNamespaceToSaveAnnotations(options?.namespaceToSaveAnnotations);
|
openmct.annotation.setNamespaceToSaveAnnotations(options?.namespaceToSaveAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(availableTags.tags).forEach(tagKey => {
|
Object.keys(availableTags.tags).forEach((tagKey) => {
|
||||||
const tagDefinition = availableTags.tags[tagKey];
|
const tagDefinition = availableTags.tags[tagKey];
|
||||||
openmct.annotation.defineTag(tagKey, tagDefinition);
|
openmct.annotation.defineTag(tagKey, tagDefinition);
|
||||||
});
|
});
|
||||||
|
@ -24,41 +24,46 @@ import EventEmitter from 'EventEmitter';
|
|||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import createExampleUser from './exampleUserCreator';
|
import createExampleUser from './exampleUserCreator';
|
||||||
|
|
||||||
const STATUSES = [{
|
const STATUSES = [
|
||||||
key: "NO_STATUS",
|
{
|
||||||
label: "Not set",
|
key: 'NO_STATUS',
|
||||||
iconClass: "icon-question-mark",
|
label: 'Not set',
|
||||||
iconClassPoll: "icon-status-poll-question-mark"
|
iconClass: 'icon-question-mark',
|
||||||
}, {
|
iconClassPoll: 'icon-status-poll-question-mark'
|
||||||
key: "GO",
|
},
|
||||||
label: "Go",
|
{
|
||||||
iconClass: "icon-check",
|
key: 'GO',
|
||||||
iconClassPoll: "icon-status-poll-question-mark",
|
label: 'Go',
|
||||||
statusClass: "s-status-ok",
|
iconClass: 'icon-check',
|
||||||
statusBgColor: "#33cc33",
|
iconClassPoll: 'icon-status-poll-question-mark',
|
||||||
statusFgColor: "#000"
|
statusClass: 's-status-ok',
|
||||||
}, {
|
statusBgColor: '#33cc33',
|
||||||
key: "MAYBE",
|
statusFgColor: '#000'
|
||||||
label: "Maybe",
|
},
|
||||||
iconClass: "icon-alert-triangle",
|
{
|
||||||
iconClassPoll: "icon-status-poll-question-mark",
|
key: 'MAYBE',
|
||||||
statusClass: "s-status-warning",
|
label: 'Maybe',
|
||||||
statusBgColor: "#ffb66c",
|
iconClass: 'icon-alert-triangle',
|
||||||
statusFgColor: "#000"
|
iconClassPoll: 'icon-status-poll-question-mark',
|
||||||
}, {
|
statusClass: 's-status-warning',
|
||||||
key: "NO_GO",
|
statusBgColor: '#ffb66c',
|
||||||
label: "No go",
|
statusFgColor: '#000'
|
||||||
iconClass: "icon-circle-slash",
|
},
|
||||||
iconClassPoll: "icon-status-poll-question-mark",
|
{
|
||||||
statusClass: "s-status-error",
|
key: 'NO_GO',
|
||||||
statusBgColor: "#9900cc",
|
label: 'No go',
|
||||||
statusFgColor: "#fff"
|
iconClass: 'icon-circle-slash',
|
||||||
}];
|
iconClassPoll: 'icon-status-poll-question-mark',
|
||||||
|
statusClass: 's-status-error',
|
||||||
|
statusBgColor: '#9900cc',
|
||||||
|
statusFgColor: '#fff'
|
||||||
|
}
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* @implements {StatusUserProvider}
|
* @implements {StatusUserProvider}
|
||||||
*/
|
*/
|
||||||
export default class ExampleUserProvider extends EventEmitter {
|
export default class ExampleUserProvider extends EventEmitter {
|
||||||
constructor(openmct, {defaultStatusRole} = {defaultStatusRole: undefined}) {
|
constructor(openmct, { defaultStatusRole } = { defaultStatusRole: undefined }) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
@ -155,7 +160,7 @@ export default class ExampleUserProvider extends EventEmitter {
|
|||||||
question: pollQuestion,
|
question: pollQuestion,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
this.emit("pollQuestionChange", this.pollQuestion);
|
this.emit('pollQuestionChange', this.pollQuestion);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -177,17 +182,17 @@ export default class ExampleUserProvider extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formStructure = {
|
const formStructure = {
|
||||||
title: "Login",
|
title: 'Login',
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
rows: [
|
rows: [
|
||||||
{
|
{
|
||||||
key: "username",
|
key: 'username',
|
||||||
control: "textfield",
|
control: 'textfield',
|
||||||
name: "Username",
|
name: 'Username',
|
||||||
pattern: "\\S+",
|
pattern: '\\S+',
|
||||||
required: true,
|
required: true,
|
||||||
cssClass: "l-input-lg",
|
cssClass: 'l-input-lg',
|
||||||
value: ''
|
value: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -205,7 +210,8 @@ export default class ExampleUserProvider extends EventEmitter {
|
|||||||
this.user = new this.ExampleUser(id, info.username, ['example-role']);
|
this.user = new this.ExampleUser(id, info.username, ['example-role']);
|
||||||
this.loggedIn = true;
|
this.loggedIn = true;
|
||||||
},
|
},
|
||||||
() => { // user canceled, setting a default username
|
() => {
|
||||||
|
// user canceled, setting a default username
|
||||||
this.user = new this.ExampleUser(id, 'Pat', ['example-role']);
|
this.user = new this.ExampleUser(id, 'Pat', ['example-role']);
|
||||||
this.loggedIn = true;
|
this.loggedIn = true;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,12 @@
|
|||||||
|
|
||||||
import ExampleUserProvider from './ExampleUserProvider';
|
import ExampleUserProvider from './ExampleUserProvider';
|
||||||
|
|
||||||
export default function ExampleUserPlugin({autoLoginUser, defaultStatusRole} = {
|
export default function ExampleUserPlugin(
|
||||||
|
{ autoLoginUser, defaultStatusRole } = {
|
||||||
autoLoginUser: 'guest',
|
autoLoginUser: 'guest',
|
||||||
defaultStatusRole: 'test-role'
|
defaultStatusRole: 'test-role'
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
const userProvider = new ExampleUserProvider(openmct, {
|
const userProvider = new ExampleUserProvider(openmct, {
|
||||||
defaultStatusRole
|
defaultStatusRole
|
||||||
|
@ -20,13 +20,10 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import {
|
import { createOpenMct, resetApplicationState } from '../../src/utils/testing';
|
||||||
createOpenMct,
|
|
||||||
resetApplicationState
|
|
||||||
} from '../../src/utils/testing';
|
|
||||||
import ExampleUserProvider from './ExampleUserProvider';
|
import ExampleUserProvider from './ExampleUserProvider';
|
||||||
|
|
||||||
describe("The Example User Plugin", () => {
|
describe('The Example User Plugin', () => {
|
||||||
let openmct;
|
let openmct;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -20,12 +20,9 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import {
|
import { createOpenMct, resetApplicationState } from '../../src/utils/testing';
|
||||||
createOpenMct,
|
|
||||||
resetApplicationState
|
|
||||||
} from '../../src/utils/testing';
|
|
||||||
|
|
||||||
describe("The Example Fault Source Plugin", () => {
|
describe('The Example Fault Source Plugin', () => {
|
||||||
let openmct;
|
let openmct;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -43,11 +43,14 @@ const getRandom = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function shelveFault(fault, opts = {
|
function shelveFault(
|
||||||
|
fault,
|
||||||
|
opts = {
|
||||||
shelved: true,
|
shelved: true,
|
||||||
comment: '',
|
comment: '',
|
||||||
shelveDuration: 90000
|
shelveDuration: 90000
|
||||||
}) {
|
}
|
||||||
|
) {
|
||||||
fault.shelved = true;
|
fault.shelved = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -1,37 +1,32 @@
|
|||||||
define([
|
define(['lodash'], function (_) {
|
||||||
'lodash'
|
|
||||||
], function (
|
|
||||||
_
|
|
||||||
) {
|
|
||||||
|
|
||||||
var METADATA_BY_TYPE = {
|
var METADATA_BY_TYPE = {
|
||||||
'generator': {
|
generator: {
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: 'name',
|
||||||
name: "Name",
|
name: 'Name',
|
||||||
format: "string"
|
format: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "utc",
|
key: 'utc',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "yesterday",
|
key: 'yesterday',
|
||||||
name: "Yesterday",
|
name: 'Yesterday',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 2
|
domain: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "wavelengths",
|
key: 'wavelengths',
|
||||||
name: "Wavelength",
|
name: 'Wavelength',
|
||||||
unit: "nm",
|
unit: 'nm',
|
||||||
format: 'string[]',
|
format: 'string[]',
|
||||||
hints: {
|
hints: {
|
||||||
range: 4
|
range: 4
|
||||||
@ -48,26 +43,26 @@ define([
|
|||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
key: "sin",
|
key: 'sin',
|
||||||
name: "Sine",
|
name: 'Sine',
|
||||||
unit: "Hz",
|
unit: 'Hz',
|
||||||
formatString: '%0.2f',
|
formatString: '%0.2f',
|
||||||
hints: {
|
hints: {
|
||||||
range: 1
|
range: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "cos",
|
key: 'cos',
|
||||||
name: "Cosine",
|
name: 'Cosine',
|
||||||
unit: "deg",
|
unit: 'deg',
|
||||||
formatString: '%0.2f',
|
formatString: '%0.2f',
|
||||||
hints: {
|
hints: {
|
||||||
range: 2
|
range: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "intensities",
|
key: 'intensities',
|
||||||
name: "Intensities",
|
name: 'Intensities',
|
||||||
format: 'number[]',
|
format: 'number[]',
|
||||||
hints: {
|
hints: {
|
||||||
range: 3
|
range: 3
|
||||||
@ -78,40 +73,40 @@ define([
|
|||||||
'example.state-generator': {
|
'example.state-generator': {
|
||||||
values: [
|
values: [
|
||||||
{
|
{
|
||||||
key: "name",
|
key: 'name',
|
||||||
name: "Name",
|
name: 'Name',
|
||||||
format: "string"
|
format: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "utc",
|
key: 'utc',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 1
|
domain: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "local",
|
key: 'local',
|
||||||
name: "Time",
|
name: 'Time',
|
||||||
format: "utc",
|
format: 'utc',
|
||||||
source: "utc",
|
source: 'utc',
|
||||||
hints: {
|
hints: {
|
||||||
domain: 2
|
domain: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "state",
|
key: 'state',
|
||||||
source: "value",
|
source: 'value',
|
||||||
name: "State",
|
name: 'State',
|
||||||
format: "enum",
|
format: 'enum',
|
||||||
enumerations: [
|
enumerations: [
|
||||||
{
|
{
|
||||||
value: 0,
|
value: 0,
|
||||||
string: "OFF"
|
string: 'OFF'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
string: "ON"
|
string: 'ON'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
hints: {
|
hints: {
|
||||||
@ -119,8 +114,8 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "value",
|
key: 'value',
|
||||||
name: "Value",
|
name: 'Value',
|
||||||
hints: {
|
hints: {
|
||||||
range: 2
|
range: 2
|
||||||
}
|
}
|
||||||
@ -129,22 +124,15 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function GeneratorMetadataProvider() {
|
function GeneratorMetadataProvider() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
||||||
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
|
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
||||||
return Object.assign(
|
return Object.assign({}, domainObject.telemetry, METADATA_BY_TYPE[domainObject.type]);
|
||||||
{},
|
|
||||||
domainObject.telemetry,
|
|
||||||
METADATA_BY_TYPE[domainObject.type]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return GeneratorMetadataProvider;
|
return GeneratorMetadataProvider;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -20,12 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define(['./WorkerInterface'], function (WorkerInterface) {
|
||||||
'./WorkerInterface'
|
|
||||||
], function (
|
|
||||||
WorkerInterface
|
|
||||||
) {
|
|
||||||
|
|
||||||
var REQUEST_DEFAULTS = {
|
var REQUEST_DEFAULTS = {
|
||||||
amplitude: 1,
|
amplitude: 1,
|
||||||
period: 10,
|
period: 10,
|
||||||
@ -46,8 +41,7 @@ define([
|
|||||||
return domainObject.type === 'generator';
|
return domainObject.type === 'generator';
|
||||||
};
|
};
|
||||||
|
|
||||||
GeneratorProvider.prototype.supportsRequest =
|
GeneratorProvider.prototype.supportsRequest = GeneratorProvider.prototype.supportsSubscribe =
|
||||||
GeneratorProvider.prototype.supportsSubscribe =
|
|
||||||
GeneratorProvider.prototype.canProvideTelemetry;
|
GeneratorProvider.prototype.canProvideTelemetry;
|
||||||
|
|
||||||
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
||||||
@ -67,7 +61,10 @@ define([
|
|||||||
var workerRequest = {};
|
var workerRequest = {};
|
||||||
|
|
||||||
props.forEach(function (prop) {
|
props.forEach(function (prop) {
|
||||||
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
|
if (
|
||||||
|
domainObject.telemetry &&
|
||||||
|
Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)
|
||||||
|
) {
|
||||||
workerRequest[prop] = domainObject.telemetry[prop];
|
workerRequest[prop] = domainObject.telemetry[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([], function () {
|
||||||
|
|
||||||
], function (
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
var PURPLE = {
|
var PURPLE = {
|
||||||
sin: 2.2,
|
sin: 2.2,
|
||||||
cos: 2.2
|
cos: 2.2
|
||||||
@ -48,34 +43,32 @@ define([
|
|||||||
},
|
},
|
||||||
LIMITS = {
|
LIMITS = {
|
||||||
rh: {
|
rh: {
|
||||||
cssClass: "is-limit--upr is-limit--red",
|
cssClass: 'is-limit--upr is-limit--red',
|
||||||
low: RED,
|
low: RED,
|
||||||
high: Number.POSITIVE_INFINITY,
|
high: Number.POSITIVE_INFINITY,
|
||||||
name: "Red High"
|
name: 'Red High'
|
||||||
},
|
},
|
||||||
rl: {
|
rl: {
|
||||||
cssClass: "is-limit--lwr is-limit--red",
|
cssClass: 'is-limit--lwr is-limit--red',
|
||||||
high: -RED,
|
high: -RED,
|
||||||
low: Number.NEGATIVE_INFINITY,
|
low: Number.NEGATIVE_INFINITY,
|
||||||
name: "Red Low"
|
name: 'Red Low'
|
||||||
},
|
},
|
||||||
yh: {
|
yh: {
|
||||||
cssClass: "is-limit--upr is-limit--yellow",
|
cssClass: 'is-limit--upr is-limit--yellow',
|
||||||
low: YELLOW,
|
low: YELLOW,
|
||||||
high: RED,
|
high: RED,
|
||||||
name: "Yellow High"
|
name: 'Yellow High'
|
||||||
},
|
},
|
||||||
yl: {
|
yl: {
|
||||||
cssClass: "is-limit--lwr is-limit--yellow",
|
cssClass: 'is-limit--lwr is-limit--yellow',
|
||||||
low: -RED,
|
low: -RED,
|
||||||
high: -YELLOW,
|
high: -YELLOW,
|
||||||
name: "Yellow Low"
|
name: 'Yellow Low'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function SinewaveLimitProvider() {
|
function SinewaveLimitProvider() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SinewaveLimitProvider.prototype.supportsLimits = function (domainObject) {
|
SinewaveLimitProvider.prototype.supportsLimits = function (domainObject) {
|
||||||
return domainObject.type === 'generator';
|
return domainObject.type === 'generator';
|
||||||
@ -106,62 +99,61 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
SinewaveLimitProvider.prototype.getLimits = function (domainObject) {
|
SinewaveLimitProvider.prototype.getLimits = function (domainObject) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
limits: function () {
|
limits: function () {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
WATCH: {
|
WATCH: {
|
||||||
low: {
|
low: {
|
||||||
color: "cyan",
|
color: 'cyan',
|
||||||
sin: -CYAN.sin,
|
sin: -CYAN.sin,
|
||||||
cos: -CYAN.cos
|
cos: -CYAN.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "cyan",
|
color: 'cyan',
|
||||||
...CYAN
|
...CYAN
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
WARNING: {
|
WARNING: {
|
||||||
low: {
|
low: {
|
||||||
color: "yellow",
|
color: 'yellow',
|
||||||
sin: -YELLOW.sin,
|
sin: -YELLOW.sin,
|
||||||
cos: -YELLOW.cos
|
cos: -YELLOW.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "yellow",
|
color: 'yellow',
|
||||||
...YELLOW
|
...YELLOW
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DISTRESS: {
|
DISTRESS: {
|
||||||
low: {
|
low: {
|
||||||
color: "orange",
|
color: 'orange',
|
||||||
sin: -ORANGE.sin,
|
sin: -ORANGE.sin,
|
||||||
cos: -ORANGE.cos
|
cos: -ORANGE.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "orange",
|
color: 'orange',
|
||||||
...ORANGE
|
...ORANGE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CRITICAL: {
|
CRITICAL: {
|
||||||
low: {
|
low: {
|
||||||
color: "red",
|
color: 'red',
|
||||||
sin: -RED.sin,
|
sin: -RED.sin,
|
||||||
cos: -RED.cos
|
cos: -RED.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "red",
|
color: 'red',
|
||||||
...RED
|
...RED
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SEVERE: {
|
SEVERE: {
|
||||||
low: {
|
low: {
|
||||||
color: "purple",
|
color: 'purple',
|
||||||
sin: -PURPLE.sin,
|
sin: -PURPLE.sin,
|
||||||
cos: -PURPLE.cos
|
cos: -PURPLE.cos
|
||||||
},
|
},
|
||||||
high: {
|
high: {
|
||||||
color: "purple",
|
color: 'purple',
|
||||||
...PURPLE
|
...PURPLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user