Skip to content

Commit

Permalink
Firmware UI: Convert firmware_update_test to TS
Browse files Browse the repository at this point in the history
- Rename file from JS to TS and update BUILD.gn.
- Remove closure type comments.
- Update property and function names to match TS style guide.

Bug: b:304299225
Test: browser_tests --gtest_filter=*FirmwareUpdate*
Change-Id: I0e1fff465e63044c7255dad74ba20b7403552fb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4928875
Reviewed-by: Michael Checo <michaelcheco@google.com>
Commit-Queue: Ashley Prasad <ashleydp@google.com>
Cr-Commit-Position: refs/heads/main@{#1210510}
  • Loading branch information
Ashley Prasad authored and Chromium LUCI CQ committed Oct 16, 2023
1 parent 772a42e commit 91d5c98
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 92 deletions.
2 changes: 1 addition & 1 deletion chrome/test/data/webui/chromeos/firmware_update/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ build_webui_tests("build_webui_tests") {
"fake_update_controller_test.ts",
"fake_update_provider_test.ts",
"firmware_update_dialog_test.ts",
"firmware_update_test.js",
"firmware_update_test.ts",
"firmware_update_unified_test.js",
"peripheral_updates_list_test.js",
"update_card_test.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,149 +2,171 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import 'chrome://resources/cr_elements/cr_button/cr_button.js';
import 'chrome://accessory-update/firmware_update_app.js';

import {fakeFirmwareUpdates} from 'chrome://accessory-update/fake_data.js';
import {FakeUpdateController} from 'chrome://accessory-update/fake_update_controller.js';
import {FakeUpdateProvider} from 'chrome://accessory-update/fake_update_provider.js';
import {UpdateState} from 'chrome://accessory-update/firmware_update.mojom-webui.js';
import {FirmwareUpdate, UpdateState} from 'chrome://accessory-update/firmware_update.mojom-webui.js';
import {FirmwareUpdateAppElement} from 'chrome://accessory-update/firmware_update_app.js';
import {FirmwareUpdateDialogElement} from 'chrome://accessory-update/firmware_update_dialog.js';
import {getUpdateProvider, setUpdateControllerForTesting, setUpdateProviderForTesting} from 'chrome://accessory-update/mojo_interface_provider.js';
import {UpdateCardElement} from 'chrome://accessory-update/update_card.js';
import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js';
import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js';
import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
import {assert} from 'chrome://resources/js/assert.js';
import {mojoString16ToString} from 'chrome://resources/js/mojo_type_util.js';
import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';

import {eventToPromise} from '../test_util.js';
import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';

export function firmwareUpdateAppTest() {
/** @type {?FirmwareUpdateAppElement} */
let page = null;
let page: FirmwareUpdateAppElement|null = null;

/** @type {?FakeUpdateProvider} */
let provider = null;
let provider: FakeUpdateProvider|null = null;

/** @type {?FakeUpdateController} */
let controller = null;
let controller: FakeUpdateController|null = null;

setup(() => {
// @ts-ignore
document.body.innerHTML = window.trustedTypes.emptyHTML;
controller = new FakeUpdateController();
controller.setUpdateIntervalInMs(0);
setUpdateControllerForTesting(controller);
provider = new FakeUpdateProvider();
setUpdateProviderForTesting(provider);
provider.setFakeFirmwareUpdates(fakeFirmwareUpdates);
provider?.setFakeFirmwareUpdates(fakeFirmwareUpdates);
});

teardown(() => {
controller.reset();
controller?.reset();
controller = null;
provider.reset();
provider?.reset();
provider = null;
page.remove();
page?.remove();
page = null;
});

function initializePage() {
page = /** @type {!FirmwareUpdateAppElement} */ (
document.createElement('firmware-update-app'));
function initializePage(): void {
page = document.createElement('firmware-update-app') as
FirmwareUpdateAppElement;
assert(!!page);
document.body.appendChild(page);
}

/** @return {!CrDialogElement} */
function getConfirmationDialog() {
return page.shadowRoot.querySelector('firmware-confirmation-dialog')
.shadowRoot.querySelector('#confirmationDialog');
function getConfirmationDialog(): CrDialogElement {
assert(page);
const fwConfirmDialog = strictQuery(
'firmware-confirmation-dialog', page.shadowRoot, HTMLElement)!;
assert(fwConfirmDialog);
const confirmDialog = strictQuery(
'#confirmationDialog', fwConfirmDialog.shadowRoot, CrDialogElement)!;
assert(confirmDialog);
return confirmDialog;
}

/** @return {!Promise} */
function confirmUpdate() {
function confirmUpdate(): Promise<void> {
const confirmationDialog = getConfirmationDialog();
assertTrue(confirmationDialog.open);
confirmationDialog.querySelector('#nextButton').click();
const nextButton =
strictQuery('#nextButton', confirmationDialog, CrButtonElement);
assert(nextButton);
nextButton.click();
return flushTasks();
}

/** @return {!Promise} */
function cancelUpdate() {
function cancelUpdate(): Promise<void> {
const confirmationDialog = getConfirmationDialog();
assertTrue(confirmationDialog.open);
confirmationDialog.querySelector('#cancelButton').click();
const cancelButton =
strictQuery('#cancelButton', confirmationDialog, CrButtonElement);
assert(cancelButton);
cancelButton.click();
return flushTasks();
}

/** @return {!CrDialogElement} */
function getUpdateDialog() {
return page.shadowRoot.querySelector('firmware-update-dialog')
.shadowRoot.querySelector('#updateDialog');
function getFirmwareUpdateDialog(): FirmwareUpdateDialogElement {
assert(page);
return strictQuery(
'firmware-update-dialog', page.shadowRoot, FirmwareUpdateDialogElement)!
;
}

function getUpdateDialog(): CrDialogElement {
return strictQuery(
'#updateDialog', getFirmwareUpdateDialog().shadowRoot, CrDialogElement)!
;
}

/** @return {!Array<!UpdateCardElement>} */
function getUpdateCards() {
const updateList = page.shadowRoot.querySelector('peripheral-updates-list');
return updateList.shadowRoot.querySelectorAll('update-card');
function getUpdateCards(): UpdateCardElement[] {
assert(page);
const updateList =
page.shadowRoot!.querySelector('peripheral-updates-list')!;
const updateCards = updateList.shadowRoot!.querySelectorAll('update-card');
return Array.from(updateCards);
}

/**
* @param {!CrDialogElement} dialogElement
*/
function getNextButton(dialogElement) {
return /** @type {!CrButtonElement} */ (
dialogElement.querySelector('#nextButton'));
function getUpdateState(): UpdateState {
return getFirmwareUpdateDialog()!.installationProgress!.state;
}

/** @return {!UpdateState} */
function getUpdateState() {
return page.shadowRoot.querySelector('firmware-update-dialog')
.installationProgress.state;
function getFirmwareUpdateFromDialog(): FirmwareUpdate|null {
return getFirmwareUpdateDialog().update;
}

/** @return {!FirmwareUpdate} */
function getFirmwareUpdateFromDialog() {
return page.shadowRoot.querySelector('firmware-update-dialog').update;
function getUpdateDialogTitle(): HTMLDivElement {
return strictQuery(
'#updateDialogTitle', getFirmwareUpdateDialog().shadowRoot,
HTMLDivElement);
}

function getUpdateDialogTitle() {
return /** @type {!HTMLDivElement} */ (
page.shadowRoot.querySelector('firmware-update-dialog')
.shadowRoot.querySelector('#updateDialogTitle'));
function getFakeFirmwareUpdate(
arrayIndex: number, updateIndex: number): FirmwareUpdate {
const arr = fakeFirmwareUpdates[arrayIndex];
assert(arr);
const update = arr[updateIndex];
assert(update);
return update;
}

test('SettingGettingTestProvider', () => {
initializePage();
const fake_provider =
/** @type {!UpdateProviderInterface} */ (new FakeUpdateProvider());
const fake_provider = new FakeUpdateProvider();
setUpdateProviderForTesting(fake_provider);
assertEquals(fake_provider, getUpdateProvider());
});

test('OpenConfirmationDialog', async () => {
initializePage();
await flushTasks();
assert(page);
// Open dialog for first firmware update card.
const whenFired =
eventToPromise('cr-dialog-open', /** @type {!Element}*/ (page));
getUpdateCards()[0].shadowRoot.querySelector(`#updateButton`).click();
const whenFired = eventToPromise('cr-dialog-open', page);
const button = strictQuery(
`#updateButton`, getUpdateCards()[0]!.shadowRoot, CrButtonElement);
button.click();
await flushTasks();
return whenFired
.then(() => {
assertTrue(getConfirmationDialog().open);
return cancelUpdate();
})
.then(() => assertFalse(!!getConfirmationDialog()));
await whenFired;
assertTrue(!!getConfirmationDialog(), 'Confirmation dialog exists');
assertTrue(getConfirmationDialog().open, 'Confirmation dialog is open');
await cancelUpdate();
const fwConfirmDialog = strictQuery(
'firmware-confirmation-dialog', page.shadowRoot, HTMLElement);
assertFalse(isVisible(
fwConfirmDialog.shadowRoot!.querySelector('#confirmationDialog')));
});

test('OpenUpdateDialog', async () => {
initializePage();
await flushTasks();
// Open dialog for first firmware update card.
getUpdateCards()[0].shadowRoot.querySelector(`#updateButton`).click();
const button = strictQuery(
`#updateButton`, getUpdateCards()[0]!.shadowRoot, CrButtonElement);
button.click();
await flushTasks();
const whenFired =
eventToPromise('cr-dialog-open', /** @type {!Element}*/ (page));
const whenFired = eventToPromise('cr-dialog-open', page!);
await confirmUpdate();
// Process |OnProgressChanged| call.
await flushTasks();
Expand All @@ -155,28 +177,29 @@ export function firmwareUpdateAppTest() {
initializePage();
await flushTasks();
// Open dialog for firmware update.
getUpdateCards()[1].shadowRoot.querySelector(`#updateButton`).click();
const button = strictQuery(
`#updateButton`, getUpdateCards()[1]!.shadowRoot, CrButtonElement);
button.click();
await flushTasks();
const whenFired =
eventToPromise('cr-dialog-open', /** @type {!Element}*/ (page));
const whenFired = eventToPromise('cr-dialog-open', page!);
await confirmUpdate();
// Process |OnProgressChanged| call.
await flushTasks();
return whenFired
.then(() => {
assertEquals(UpdateState.kUpdating, getUpdateState());
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog();
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog()!;
assertEquals(
loadTimeData.getStringF(
'updating',
mojoString16ToString(fakeFirmwareUpdate.deviceName)),
getUpdateDialogTitle().innerText.trim());
// Allow firmware update to complete.
return controller.getUpdateCompletedPromiseForTesting();
return controller?.getUpdateCompletedPromiseForTesting();
})
.then(() => flushTasks())
.then(() => {
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog();
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog()!;
assertEquals(UpdateState.kSuccess, getUpdateState());
assertTrue(getUpdateDialog().open);
assertEquals(
Expand All @@ -192,27 +215,28 @@ export function firmwareUpdateAppTest() {
await flushTasks();
// Open dialog for firmware update. The third fake update in the list
// will fail.
getUpdateCards()[2].shadowRoot.querySelector(`#updateButton`).click();
const button = strictQuery(
`#updateButton`, getUpdateCards()[2]!.shadowRoot, CrButtonElement);
button.click();
await flushTasks();
const whenFired =
eventToPromise('cr-dialog-open', /** @type {!Element}*/ (page));
const whenFired = eventToPromise('cr-dialog-open', page!);
await confirmUpdate();
// Process |OnProgressChanged| call.
await flushTasks();
return whenFired
.then(() => {
assertEquals(UpdateState.kUpdating, getUpdateState());
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog();
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog()!;
assertEquals(
loadTimeData.getStringF(
'updating',
mojoString16ToString(fakeFirmwareUpdate.deviceName)),
getUpdateDialogTitle().innerText.trim());
return controller.getUpdateCompletedPromiseForTesting();
return controller?.getUpdateCompletedPromiseForTesting();
})
.then(() => flushTasks())
.then(() => {
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog();
const fakeFirmwareUpdate = getFirmwareUpdateFromDialog()!;
assertEquals(UpdateState.kFailed, getUpdateState());
assertTrue(getUpdateDialog().open);
assertEquals(
Expand All @@ -225,44 +249,44 @@ export function firmwareUpdateAppTest() {

test('InflightUpdate', async () => {
// Simulate an inflight update is already in progress.
provider.setInflightUpdate(fakeFirmwareUpdates[0][0]);
provider?.setInflightUpdate(getFakeFirmwareUpdate(0, 0));
initializePage();
await flushTasks();
await flushTasks();

// Simulate InstallProgressChangedObserver being called.
controller.beginUpdate('fakeDeviceId', {path: 'fake.cab'});
controller?.beginUpdate('fakeDeviceId', {path: 'fake.cab'});
await flushTasks();
await flushTasks();
// Check that the update dialog is now opened with an update.
assertEquals(UpdateState.kUpdating, getUpdateState());
const fakeUpdate = getFirmwareUpdateFromDialog();
const fakeUpdate = getFirmwareUpdateFromDialog()!;
assertEquals(
loadTimeData.getStringF(
'updating', mojoString16ToString(fakeUpdate.deviceName)),
getUpdateDialogTitle().innerText.trim());
// Allow firmware update to complete.
await controller.getUpdateCompletedPromiseForTesting();
await controller?.getUpdateCompletedPromiseForTesting();
await flushTasks();
assertEquals(UpdateState.kSuccess, getUpdateState());
assertTrue(getUpdateDialog().open);
});

test('InflightUpdateNoProgressUpdate', async () => {
// Simulate an inflight update is already in progress.
provider.setInflightUpdate(fakeFirmwareUpdates[0][0]);
provider?.setInflightUpdate(getFakeFirmwareUpdate(0, 0));
initializePage();
await flushTasks();
await flushTasks();

// Check that the update dialog is now opened with an update.
assertEquals(UpdateState.kIdle, getUpdateState());
const fakeUpdate = getFirmwareUpdateFromDialog();
const fakeUpdate = getFirmwareUpdateFromDialog()!;
assertTrue(!!fakeUpdate);
assertTrue(getUpdateDialog().open);
});

test('UpdatesCSSWhenIsJellyEnabledForFirmwareAppSet', async () => {
/* @type {HTMLLinkElement} */
const linkEl = document.createElement('link');
const disabledUrl = 'chrome://resources/chromeos/colors/cros_styles.css';
linkEl.href = disabledUrl;
Expand All @@ -275,12 +299,11 @@ export function firmwareUpdateAppTest() {
initializePage();
await flushTasks();

assertTrue(linkEl.href.includes(disabledUrl));
assertTrue(linkEl.href.includes(disabledUrl), 'Has cros_styles');

// Clear app element.
page.remove();
page = null;
document.body.innerHTML = trustedTypes.emptyHTML;
page?.remove();
await flushTasks();

// Setup for jelly disabled.
loadTimeData.overrideValues({
Expand All @@ -290,7 +313,7 @@ export function firmwareUpdateAppTest() {
await flushTasks();

const enabledUrl = 'chrome://theme/colors.css';
assertTrue(linkEl.href.includes(enabledUrl));
assertTrue(linkEl.href.includes(enabledUrl), 'Has theme/colors');

// Clean up.
document.head.removeChild(linkEl);
Expand Down

0 comments on commit 91d5c98

Please sign in to comment.