Skip to content

Commit

Permalink
[Mobile] Add Global Search to Mobile (#7477)
Browse files Browse the repository at this point in the history
* Add status area back to mobile

* Make search results responsive to width

* Make clear search button always visible, regardless of hover

* Make clear search button visible, and fix weird margin in top left corner

* Fix input width, add logic to make close button work properly, fix margin on results so there is room for close button, fix various landscape mode issues

* update mobile testing

* Fix dropdown sizes, remove shadows and corners to make it look less like a popup and more full screen

* Add animation and persist search bar in mobile

* Fix linting issues

* Fix padding in Desktop

* fix padding in status area

* fix bad merge

* lint fixes

* fix bad merge... again

* again

* fixes to mobile

* update tests

* lint fix

* test fixes

---------

Co-authored-by: John Hill <[email protected]>
  • Loading branch information
rukmini-bose and unlikelyzero authored Feb 21, 2024
1 parent 6bbabf9 commit 6393a77
Show file tree
Hide file tree
Showing 17 changed files with 304 additions and 42 deletions.
33 changes: 30 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,31 @@ jobs:
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:
- generate_and_store_version_and_filesystem_artifacts
e2e-mobile:
executor: pw-focal-development
steps:
- build_and_install:
node-version: lts/hydrogen
- run: npm run test:e2e:mobile
- when:
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
steps:
- generate_e2e_code_cov_report:
suite: full
- store_test_results:
path: test-results/results.xml
- store_artifacts:
path: test-results
- store_artifacts:
path: coverage
- store_artifacts:
path: html-test-results
- when:
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
steps:
- generate_and_store_version_and_filesystem_artifacts
e2e-couchdb:
executor: ubuntu
steps:
Expand Down Expand Up @@ -260,8 +285,9 @@ workflows:
- e2e-test:
name: e2e-stable
suite: stable
- e2e-mobile
- visual-a11y-tests:
name: visual-test-ci
name: visual-a11y-test-ci
suite: ci

the-nightly: #These jobs do not run on PRs, but against master at night
Expand All @@ -277,10 +303,11 @@ workflows:
- e2e-test:
name: e2e-full-nightly
suite: full
- mem-test
- e2e-mobile
- perf-test
- mem-test
- visual-a11y-tests:
name: visual-test-nightly
name: visual-a11y-test-nightly
suite: full
- e2e-couchdb
triggers:
Expand Down
12 changes: 9 additions & 3 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ Current list of test tags:

|Test Tag|Description|
|:-:|-|
|`@ipad` | Test case or test suite is compatible with Playwright's iPad support and Open MCT's read-only mobile view (i.e. no create button).|
|`@mobile` | Test case or test suite is compatible with Playwright's iPad support and Open MCT's read-only mobile view (i.e. no create button).|
|`@a11y` | Test case or test suite to execute playwright-axe accessibility checks and generate a11y reports.|
|`@gds` | Denotes a GDS Test Case used in the VIPER Mission.|
|`@addInit` | Initializes the browser with an injected and artificial state. Useful for loading non-default plugins. Likely will not work outside of `npm start`.|
Expand Down Expand Up @@ -329,9 +329,15 @@ In terms of operating system testing, we're only limited by what the CI provider

#### **Mobile**

We have the Mission-need to support iPad. To run our iPad suite, please see our `playwright-*.config.js` with the 'iPad' project.
We have a Mission-need to support iPad and mobile devices. To run our test suites with mobile devices, please see our `playwright-mobile.config.js` projects.

In general, our test suite is not designed to run against mobile devices as the mobile experience is a focused version of the application. Core functionality is missing (chiefly the 'Create' button) and so this will likely turn into a separate suite.
In general, our test suite is not designed to run against mobile devices as the mobile experience is a focused version of the application. Core functionality is missing (chiefly the 'Create' button). To bypass the object creation, we leverage the `storageState` properties for starting the mobile tests with localstorage.

For now, the mobile tests will exist in the /tests/mobile/ suites and be executed with the
```sh
npm run test:e2e:mobile
```
command.

#### **Skipping or executing tests based on browser, os, and/os browser version:**

Expand Down
1 change: 1 addition & 0 deletions e2e/playwright-ci.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const NUM_WORKERS = 2;
const config = {
retries: 2, //Retries 2 times for a total of 3 runs. When running sharded and with max-failures=5, this should ensure that flake is managed without failing the full suite
testDir: 'tests',
grepInvert: /@mobile/, //Ignore mobile tests
testIgnore: '**/*.perf.spec.js', //Ignore performance tests and define in playwright-perfromance.config.js
timeout: 60 * 1000,
webServer: {
Expand Down
20 changes: 1 addition & 19 deletions e2e/playwright-local.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// playwright.config.js
// @ts-check

// eslint-disable-next-line no-unused-vars
import { devices } from '@playwright/test';

/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
retries: 0,
testDir: 'tests',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
testIgnore: '**/*.perf.spec.js',
timeout: 30 * 1000,
webServer: {
Expand Down Expand Up @@ -35,7 +33,6 @@ const config = {
},
{
name: 'MMOC',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grepInvert: /@snapshot/,
use: {
browserName: 'chromium',
Expand All @@ -47,24 +44,20 @@ const config = {
},
{
name: 'safari',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grep: /@ipad/, // only run ipad tests due to this bug https://github.com/microsoft/playwright/issues/8340
grepInvert: /@snapshot/,
use: {
browserName: 'webkit'
}
},
{
name: 'firefox',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grepInvert: /@snapshot/,
use: {
browserName: 'firefox'
}
},
{
name: 'canary',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grepInvert: /@snapshot/,
use: {
browserName: 'chromium',
Expand All @@ -73,22 +66,11 @@ const config = {
},
{
name: 'chrome-beta',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grepInvert: /@snapshot/,
use: {
browserName: 'chromium',
channel: 'chrome-beta'
}
},
{
name: 'ipad',
testMatch: '**/*.e2e.spec.js', // only run e2e tests
grep: /@ipad/,
grepInvert: /@snapshot/,
use: {
browserName: 'webkit',
...devices['iPad (gen 7) landscape'] // Complete List https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json
}
}
],
reporter: [
Expand Down
69 changes: 69 additions & 0 deletions e2e/playwright-mobile.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// playwright.config.js
// @ts-check

import { devices } from '@playwright/test';
const MAX_FAILURES = 5;
const NUM_WORKERS = 2;

import { fileURLToPath } from 'url';

/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
retries: 1, //Retries 2 times for a total of 3 runs. When running sharded and with max-failures=5, this should ensure that flake is managed without failing the full suite
testDir: 'tests',
testIgnore: '**/*.perf.spec.js', //Ignore performance tests and define in playwright-perfromance.config.js
timeout: 30 * 1000,
webServer: {
command: 'npm run start:coverage',
url: 'http://localhost:8080/#',
timeout: 200 * 1000,
reuseExistingServer: true //This was originally disabled to prevent differences in local debugging vs. CI. However, it significantly speeds up local debugging.
},
maxFailures: MAX_FAILURES, //Limits failures to 5 to reduce CI Waste
workers: NUM_WORKERS, //Limit to 2 for CircleCI Agent
use: {
baseURL: 'http://localhost:8080/',
headless: true,
ignoreHTTPSErrors: true,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
video: 'off'
},
projects: [
{
name: 'ipad',
grep: /@mobile/,
use: {
storageState: fileURLToPath(
new URL('./test-data/display_layout_with_child_layouts.json', import.meta.url)
),
browserName: 'webkit',
...devices['iPad (gen 7) landscape'] // Complete List https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json
}
},
{
name: 'iphone',
grep: /@mobile/,
use: {
storageState: fileURLToPath(
new URL('./test-data/display_layout_with_child_layouts.json', import.meta.url)
),
browserName: 'webkit',
...devices['iPhone 14 Pro'] // Complete List https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json
}
}
],
reporter: [
['list'],
[
'html',
{
open: 'never',
outputFolder: '../html-test-results' //Must be in different location due to https://github.com/microsoft/playwright/issues/12840
}
],
['junit', { outputFile: '../test-results/results.xml' }]
]
};

export default config;
25 changes: 25 additions & 0 deletions e2e/playwright-watch.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// playwright.config.js
// @ts-check

import { devices } from '@playwright/test';
import { fileURLToPath } from 'url';

/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
retries: 0, //Retries are not needed with watch mode
Expand Down Expand Up @@ -28,6 +31,28 @@ const config = {
use: {
browserName: 'chromium'
}
},
{
name: 'ipad',
grep: /@mobile/,
use: {
storageState: fileURLToPath(
new URL('./test-data/display_layout_with_child_layouts.json', import.meta.url)
),
browserName: 'webkit',
...devices['iPad (gen 7) landscape'] // Complete List https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json
}
},
{
name: 'iphone',
grep: /@mobile/,
use: {
storageState: fileURLToPath(
new URL('./test-data/display_layout_with_child_layouts.json', import.meta.url)
),
browserName: 'webkit',
...devices['iPhone 14 Pro'] // Complete List https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json
}
}
],
reporter: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ test.describe('Example Imagery in Display Layout', () => {
await page.locator('li[title="View Large"]').click();
await expect(pausePlayButton).toHaveClass(/is-paused/);

await page.locator('[aria-label="Close"]').click();
await page.getByRole('button', { name: 'Close' }).click();
await expect.soft(pausePlayButton).not.toHaveClass(/is-paused/);
});

Expand All @@ -386,7 +386,7 @@ test.describe('Example Imagery in Display Layout', () => {
await page.locator('li[title="View Large"]').click();
await expect(pausePlayButton).toHaveClass(/is-paused/);

await page.locator('[aria-label="Close"]').click();
await page.getByRole('button', { name: 'Close' }).click();
await expect.soft(pausePlayButton).toHaveClass(/is-paused/);
});

Expand Down Expand Up @@ -509,7 +509,7 @@ test.describe('Example Imagery in Flexible layout', () => {
await page.getByRole('button', { name: 'Background Image', state: 'visible' });

// Close the large view
await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();
});

test.beforeEach(async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ test.describe('Snapshot image tests', () => {
// expect large image to be displayed
await expect(page.getByRole('dialog').getByText('favicon-96x96.png')).toBeVisible();

await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();

// drop another image onto the entry
await page.dispatchEvent('.c-snapshots', 'drop', { dataTransfer: dropTransfer });
Expand Down
6 changes: 3 additions & 3 deletions e2e/tests/functional/plugins/plot/previews.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ test.describe('Plots work in Previews', () => {
await page.getByLabel('Sine', { exact: true }).click({ button: 'right' });
await page.getByLabel('View Historical Data').click();
await expect(page.getByLabel('Preview Container').getByLabel('Plot Canvas')).toBeVisible();
await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();
await page.getByLabel('Expand Test Display Layout layout').click();

// change to a plot and ensure embiggen works
Expand All @@ -73,7 +73,7 @@ test.describe('Plots work in Previews', () => {
await expect(page.getByLabel('Preview Container')).toBeHidden();
await page.getByLabel('Large View').click();
await expect(page.getByLabel('Preview Container').getByLabel('Plot Canvas')).toBeVisible();
await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();

// get last sinewave tree item (in the display layout)
await page
Expand All @@ -83,6 +83,6 @@ test.describe('Plots work in Previews', () => {
.click({ button: 'right' });
await page.getByLabel('View', { exact: true }).click();
await expect(page.getByLabel('Preview Container').getByLabel('Plot Canvas')).toBeVisible();
await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test.describe('Preview mode', () => {
await expect(page.getByLabel('Export Table Data')).toBeVisible();
await expect(page.getByLabel('Export Marked Rows')).toBeVisible();
await page.getByRole('menuitem', { name: 'Pause' }).click();
await page.getByLabel('Close').click();
await page.getByRole('button', { name: 'Close' }).click();

await expandEntireTree(page);

Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/functional/smoke.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ test('Verify that the create button appears and that the Folder Domain Object is
await expect(page.locator(':nth-match(:text("Folder"), 2)')).toBeEnabled();
});

test('Verify that My Items Tree appears @ipad', async ({ page, openmctConfig }) => {
test('Verify that My Items Tree appears', async ({ page, openmctConfig }) => {
const { myItemsFolderName } = openmctConfig;
//Go to baseURL
await page.goto('./');
Expand Down
Loading

0 comments on commit 6393a77

Please sign in to comment.