diff --git a/tools/winscope-ng/src/app/components/collect_traces.component.ts b/tools/winscope-ng/src/app/components/collect_traces.component.ts index 0af3c1178..90f89b695 100644 --- a/tools/winscope-ng/src/app/components/collect_traces.component.ts +++ b/tools/winscope-ng/src/app/components/collect_traces.component.ts @@ -13,7 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Component, Input, Inject, Output, EventEmitter, OnInit, OnDestroy, ViewEncapsulation, ChangeDetectorRef } from "@angular/core"; +import { + ChangeDetectorRef, + Component, + EventEmitter, + Input, + Inject, + Output, + OnInit, + OnDestroy, + NgZone, + ViewEncapsulation +} from "@angular/core"; import { TraceData} from "app/trace_data"; import { ProxyConnection } from "trace_collection/proxy_connection"; import { Connection } from "trace_collection/connection"; @@ -21,7 +32,6 @@ import { ProxyState } from "trace_collection/proxy_client"; import { traceConfigurations, configMap, SelectionConfiguration, EnableConfiguration } from "trace_collection/trace_collection_utils"; import { PersistentStore } from "common/utils/persistent_store"; import { MatSnackBar } from "@angular/material/snack-bar"; -import { ParserError } from "parsers/parser_factory"; import { ParserErrorSnackBarComponent } from "./parser_error_snack_bar_component"; import { TracingConfig } from "trace_collection/tracing_config"; @@ -299,7 +309,8 @@ export class CollectTracesComponent implements OnInit, OnDestroy { constructor( @Inject(MatSnackBar) private snackBar: MatSnackBar, - @Inject(ChangeDetectorRef) private changeDetectorRef: ChangeDetectorRef + @Inject(ChangeDetectorRef) private changeDetectorRef: ChangeDetectorRef, + @Inject(NgZone) private ngZone: NgZone ) { this.connect = new ProxyConnection( (newState) => this.changeDetectorRef.detectChanges(), @@ -464,20 +475,11 @@ export class CollectTracesComponent implements OnInit, OnDestroy { this.traceData.clear(); const parserErrors = await this.traceData.loadTraces(this.connect.adbData()); - if (parserErrors.length > 0) { - this.openTempSnackBar(parserErrors); - } + ParserErrorSnackBarComponent.open(this.ngZone, this.snackBar, parserErrors); this.traceDataLoaded.emit(); console.log("finished loading data!"); } - private openTempSnackBar(parserErrors: ParserError[]) { - this.snackBar.openFromComponent(ParserErrorSnackBarComponent, { - data: parserErrors, - duration: 7500, - }); - } - private onLoadProgressUpdate(progress: number) { this.loadProgress = progress; this.changeDetectorRef.detectChanges(); diff --git a/tools/winscope-ng/src/app/components/parser_error_snack_bar_component.ts b/tools/winscope-ng/src/app/components/parser_error_snack_bar_component.ts index 47f9d2ae7..0f992fcad 100644 --- a/tools/winscope-ng/src/app/components/parser_error_snack_bar_component.ts +++ b/tools/winscope-ng/src/app/components/parser_error_snack_bar_component.ts @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {Component, Inject} from "@angular/core"; -import {MAT_SNACK_BAR_DATA, MatSnackBarRef} from "@angular/material/snack-bar"; +import {Component, Inject, NgZone} from "@angular/core"; +import {MAT_SNACK_BAR_DATA, MatSnackBar, MatSnackBarRef} from "@angular/material/snack-bar"; import {TRACE_INFO} from "app/trace_info"; import {ParserError, ParserErrorType} from "parsers/parser_factory"; @@ -46,6 +46,17 @@ import {ParserError, ParserErrorType} from "parsers/parser_factory"; export class ParserErrorSnackBarComponent { messages: string[] = []; + static open(ngZone: NgZone, snackBar: MatSnackBar, parserErrors: ParserError[]) { + ngZone.run(() => { + // The snackbar needs to be opened within ngZone, + // otherwise it will first display on the left and then will jump to the center + snackBar.openFromComponent(ParserErrorSnackBarComponent, { + data: parserErrors, + duration: 10000, + }); + }); + } + constructor( @Inject(MatSnackBarRef) public snackBarRef: MatSnackBarRef, @Inject(MAT_SNACK_BAR_DATA) errors: ParserError[] diff --git a/tools/winscope-ng/src/app/components/upload_traces.component.ts b/tools/winscope-ng/src/app/components/upload_traces.component.ts index 536ac2915..ebef809ef 100644 --- a/tools/winscope-ng/src/app/components/upload_traces.component.ts +++ b/tools/winscope-ng/src/app/components/upload_traces.component.ts @@ -13,7 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {ChangeDetectorRef, Component, EventEmitter, Inject, Input, Output} from "@angular/core"; +import { + ChangeDetectorRef, + Component, + EventEmitter, + Inject, + Input, + NgZone, + Output +} from "@angular/core"; import {MatSnackBar} from "@angular/material/snack-bar"; import {UploadTracesComponentDependencyInversion} from "./upload_traces_component_dependency_inversion"; import {TraceData} from "app/trace_data"; @@ -170,7 +178,8 @@ export class UploadTracesComponent implements UploadTracesComponentDependencyInv constructor( @Inject(ChangeDetectorRef) private changeDetectorRef: ChangeDetectorRef, - @Inject(MatSnackBar) private snackBar: MatSnackBar + @Inject(MatSnackBar) private snackBar: MatSnackBar, + @Inject(NgZone) private ngZone: NgZone ) { } @@ -212,11 +221,7 @@ export class UploadTracesComponent implements UploadTracesComponentDependencyInv this.isLoadingFiles = false; this.changeDetectorRef.detectChanges(); - this.snackBar.openFromComponent(ParserErrorSnackBarComponent, { - data: parserErrors, - duration: 10000, - }); - + ParserErrorSnackBarComponent.open(this.ngZone, this.snackBar, parserErrors); } public onViewTracesButtonClick() { diff --git a/tools/winscope-ng/src/test/e2e/cross_tool_protocol.spec.ts b/tools/winscope-ng/src/test/e2e/cross_tool_protocol.spec.ts index 1c0f2bdc6..ef8e54b6e 100644 --- a/tools/winscope-ng/src/test/e2e/cross_tool_protocol.spec.ts +++ b/tools/winscope-ng/src/test/e2e/cross_tool_protocol.spec.ts @@ -41,6 +41,7 @@ describe("Cross-Tool Protocol", () => { await sendBugreportToWinscope(); await checkWinscopeRendersUploadView(); + await closeWinscopeSnackBarIfNeeded(); await clickWinscopeViewTracesButton(); await checkWinscopeRenderedSurfaceFlingerView(); @@ -85,6 +86,11 @@ describe("Cross-Tool Protocol", () => { await E2eTestUtils.clickViewTracesButton(); }; + const closeWinscopeSnackBarIfNeeded = async () => { + await browser.switchTo().window(await getWindowHandleWinscope()); + await E2eTestUtils.closeSnackBarIfNeeded(); + }; + const waitWinscopeTabIsOpen = async () => { await browser.wait(async () => { const handles = await browser.getAllWindowHandles(); diff --git a/tools/winscope-ng/src/test/e2e/upload_traces.spec.ts b/tools/winscope-ng/src/test/e2e/upload_traces.spec.ts index ec14aa652..7a0f55482 100644 --- a/tools/winscope-ng/src/test/e2e/upload_traces.spec.ts +++ b/tools/winscope-ng/src/test/e2e/upload_traces.spec.ts @@ -28,6 +28,7 @@ describe("Upload traces", () => { it("can process bugreport", async () => { await E2eTestUtils.uploadFixture("bugreports/bugreport_stripped.zip"); + await E2eTestUtils.closeSnackBarIfNeeded(); await checkHasLoadedTraces(); await checkEmitsUnsupportedFileFormatMessages(); await checkEmitsOverriddenTracesMessages(); diff --git a/tools/winscope-ng/src/test/e2e/utils.ts b/tools/winscope-ng/src/test/e2e/utils.ts index 3fdb2ac7f..279ee660b 100644 --- a/tools/winscope-ng/src/test/e2e/utils.ts +++ b/tools/winscope-ng/src/test/e2e/utils.ts @@ -28,8 +28,16 @@ class E2eTestUtils extends CommonTestUtils { } static async clickViewTracesButton() { - const loadData = element(by.css(".load-btn")); - await loadData.click(); + const button = element(by.css(".load-btn")); + await button.click(); + } + + static async closeSnackBarIfNeeded() { + const closeButton = element(by.css(".snack-bar-action")); + const isPresent = await closeButton.isPresent(); + if (isPresent) { + await closeButton.click(); + } } } diff --git a/tools/winscope-ng/src/test/e2e/viewer_input_method_clients.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_input_method_clients.spec.ts index 3bd7b5023..808abee79 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_input_method_clients.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_input_method_clients.spec.ts @@ -24,6 +24,7 @@ describe("Viewer InputMethodClients", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/InputMethodClients.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewerPresent = await element(by.css("viewer-input-method")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_input_method_manager_service.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_input_method_manager_service.spec.ts index f2da79a12..cec5d7041 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_input_method_manager_service.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_input_method_manager_service.spec.ts @@ -24,6 +24,7 @@ describe("Viewer InputMethodManagerService", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/InputMethodManagerService.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewerPresent = await element(by.css("viewer-input-method")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_input_method_service.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_input_method_service.spec.ts index 69465d4cc..f5739a618 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_input_method_service.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_input_method_service.spec.ts @@ -24,6 +24,7 @@ describe("Viewer InputMethodService", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/InputMethodService.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewerPresent = await element(by.css("viewer-input-method")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_protolog.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_protolog.spec.ts index f0d4580fb..7249726b2 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_protolog.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_protolog.spec.ts @@ -24,6 +24,7 @@ describe("Viewer ProtoLog", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/ProtoLog.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const isViewerRendered = await element(by.css("viewer-protolog")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_screen_recording.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_screen_recording.spec.ts index ee65bce6c..3f2ed0d38 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_screen_recording.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_screen_recording.spec.ts @@ -24,6 +24,7 @@ describe("Viewer ScreenRecording", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/screen_recording_metadata_v2.mp4"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewer = element(by.css("viewer-screen-recording")); diff --git a/tools/winscope-ng/src/test/e2e/viewer_surface_flinger.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_surface_flinger.spec.ts index 726ffd15a..621d1af09 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_surface_flinger.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_surface_flinger.spec.ts @@ -24,6 +24,7 @@ describe("Viewer SurfaceFlinger", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/SurfaceFlinger.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewerPresent = await element(by.css("viewer-surface-flinger")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_transactions.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_transactions.spec.ts index e9cb6f918..d25aeaa22 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_transactions.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_transactions.spec.ts @@ -24,6 +24,7 @@ describe("Viewer Transactions", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/Transactions.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const isViewerRendered = await element(by.css("viewer-transactions")).isPresent(); diff --git a/tools/winscope-ng/src/test/e2e/viewer_window_manager.spec.ts b/tools/winscope-ng/src/test/e2e/viewer_window_manager.spec.ts index 0b2eb88e3..bd617babc 100644 --- a/tools/winscope-ng/src/test/e2e/viewer_window_manager.spec.ts +++ b/tools/winscope-ng/src/test/e2e/viewer_window_manager.spec.ts @@ -24,6 +24,7 @@ describe("Viewer WindowManager", () => { it("processes trace and renders view", async () => { await E2eTestUtils.uploadFixture("traces/elapsed_and_real_timestamp/WindowManager.pb"); + await E2eTestUtils.closeSnackBarIfNeeded(); await E2eTestUtils.clickViewTracesButton(); const viewerPresent = await element(by.css("viewer-window-manager")).isPresent();