[e2e] add e2e test for ermine session shell
This test verifies that the session shell can successfully
login a guest user (unauthenticated) and use the ask bar.
fx set workstation.chromebook-x64
fx build/pave
./topaz/shell/ermine/test/run-e2e-ermine
Bug: DNO-565
Change-Id: Iad8caa90bf06e2ca493b9c57a950a48fdbf44e04
diff --git a/packages/tests/BUILD.gn b/packages/tests/BUILD.gn
index 337d944..924f956 100644
--- a/packages/tests/BUILD.gn
+++ b/packages/tests/BUILD.gn
@@ -204,3 +204,10 @@
"//topaz/tests/dart_fidl_benchmarks",
]
}
+
+group("end_to_end") {
+ testonly = true
+ public_deps = [
+ "//topaz/shell/ermine/test/end_to_end:test",
+ ]
+}
diff --git a/shell/ermine/test/end_to_end/BUILD.gn b/shell/ermine/test/end_to_end/BUILD.gn
new file mode 100644
index 0000000..f9c1fd8
--- /dev/null
+++ b/shell/ermine/test/end_to_end/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/dart/test.gni")
+import("//build/testing/environments.gni")
+
+dart_test("ermine_session_shell_e2e_test") {
+ sources = [
+ "ermine_session_shell_test.dart",
+ ]
+
+ deps = [
+ "//sdk/testing/sl4f/client",
+ "//third_party/dart-pkg/pub/test",
+ ]
+
+ args = []
+
+ if (is_debug) {
+ args += [ "--debug" ]
+ }
+}
+
+group("test") {
+ testonly = true
+
+ deps = [
+ ":ermine_session_shell_e2e_test($host_toolchain)",
+ ]
+}
diff --git a/shell/ermine/test/end_to_end/analysis_options.yaml b/shell/ermine/test/end_to_end/analysis_options.yaml
new file mode 100644
index 0000000..03a7017
--- /dev/null
+++ b/shell/ermine/test/end_to_end/analysis_options.yaml
@@ -0,0 +1,5 @@
+# Copyright 2019 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include: ../../../../tools/analysis_options.yaml
diff --git a/shell/ermine/test/end_to_end/pubspec.yaml b/shell/ermine/test/end_to_end/pubspec.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/shell/ermine/test/end_to_end/pubspec.yaml
diff --git a/shell/ermine/test/end_to_end/test/ermine_session_shell_test.dart b/shell/ermine/test/end_to_end/test/ermine_session_shell_test.dart
new file mode 100644
index 0000000..8315575
--- /dev/null
+++ b/shell/ermine/test/end_to_end/test/ermine_session_shell_test.dart
@@ -0,0 +1,126 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:sl4f/sl4f.dart';
+import 'package:test/test.dart';
+import 'package:logging/logging.dart';
+
+final _log = Logger('ermine_e2e_test');
+
+/// Tests that the DUT running ermine can do the following:
+/// - login as guest (unauthenticated login)
+/// - show the ask_bar
+/// - execute commands via the ask_bar
+void main() {
+
+ Sl4f sl4fDriver;
+
+ setUp(() async {
+ sl4fDriver = Sl4f.fromEnvironment();
+ await sl4fDriver.startServer();
+ });
+
+ tearDown(() async {
+ await sl4fDriver.stopServer();
+ sl4fDriver.close();
+ });
+
+ test('ermine session shell guest login', () async {
+
+ // TODO: note that 'user picker' screen is changing/going away
+ // so here we use sessionctl to do guest login. Once final
+ // OOBE UI is established for Ermine, this could be revisited
+ // so as to provide for more robust testing of no-auth login.
+ bool loggedIn = await sl4fDriver.ssh('sessionctl login_guest');
+
+ if (!loggedIn) {
+ fail('unable to login guest - check user already logged in?');
+ }
+
+ // allow time for shell to startup and ask bar to show
+ await Future.delayed(Duration(seconds: 5));
+
+ // verify that ask bar is active
+ bool askBarActive = await _checkActiveComponent(
+ driver:sl4fDriver, name:'ermine_ask_module');
+
+ if (!askBarActive) {
+ fail('ask bar is not active');
+ }
+
+ // Ask bar should have focus at this point, so we should
+ // be able to inject text entry via the shell and have it
+ // enter the bar.
+
+ // Note sl4f library 'input' support doesn't currently support
+ // text or keyevents. In addition to that, input keyevent doesn't
+ // appear to support keyevents with modifiers (otherwise we could
+ // tie into the show/hide of the askbar and test with esc/ALT+space)
+
+ // As it is, here we'll just open simple browser so that we can
+ // verify launching chromium from the ask bar
+ await sl4fDriver.ssh('input text simple_browser');
+
+ // Have to drive ask bar from suggestion (can't just input
+ // 'simple_browser' text and enter). So give the suggestions
+ // a second to settle down.
+ await Future.delayed(Duration(seconds: 5));
+
+ // with the top suggestion being 'open simple_browser', we can
+ // now just inject 'enter' to trigger the action.
+ await sl4fDriver.ssh('input keyevent 40');
+
+ // allow time for simple_browser to startup
+ await Future.delayed(Duration(seconds: 10));
+
+ // verify that simple_browser is active
+ bool browserActive = await _checkActiveComponent(
+ driver:sl4fDriver, name:'simple_browser');
+
+ if (!browserActive) {
+ fail('simple_browser is not active');
+ }
+
+ return;
+ });
+}
+
+/// checks to see if the component associated with [name] is running.
+Future<bool> _checkActiveComponent({Sl4f driver, String name}) async {
+
+ Future<String> getComponents() async {
+ // Note: using 'cs' here as iquery doesn't appear to actually provide a
+ // list of these active components via the hub.
+ final process = await driver.sshProcess('cs');
+ final exitCode = await process.exitCode;
+ final stdout = await process.stdout.transform(utf8.decoder).join();
+ if (exitCode != 0) {
+ final stderr = await process.stderr.transform(utf8.decoder).join();
+ _log.severe('cs failed with exit code $exitCode');
+ if (stdout.isNotEmpty) {
+ _log.severe('cs stdout: $stdout');
+ }
+ if (stderr.isNotEmpty) {
+ _log.severe('cs stderr: $stderr');
+ }
+ return null;
+ }
+ return stdout;
+ }
+
+ final activeComponents = await getComponents();
+
+ if (activeComponents == null) {
+ return false;
+ }
+
+ final matchingActiveComponentList = activeComponents.split('\n').where((line) {
+ return line.contains(name);
+ }).toList();
+
+ return matchingActiveComponentList.isNotEmpty;
+}
+
diff --git a/shell/ermine/test/run-e2e-ermine b/shell/ermine/test/run-e2e-ermine
new file mode 100755
index 0000000..59c082e
--- /dev/null
+++ b/shell/ermine/test/run-e2e-ermine
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+### run e2e tests for ermine shell
+## Usage: ./topaz/shell/ermine/test/run-e2e-ermine
+##
+## Runs the End to End tests from the current build, against the current
+## hardware target.
+##
+## Hint:
+## Use fx --dir and/or fx -d flags to modulate the selected build directory or
+## target device.
+
+source "$(cd "$(dirname "${BASH_SOURCE[0]}")"/../../../../ && pwd)"/tools/devshell/lib/vars.sh
+fx-config-read
+
+fx-command-run serve-updates &
+# To ensure any children of the above get the signal, we kill our whole process
+# group.
+trap "trap - EXIT; kill 0" EXIT
+sleep 3
+
+export FUCHSIA_IPV4_ADDR=$(fx-command-run shell ifconfig eth | perl -n -e 'print $1 if /inet addr:(\S*)/')
+
+if [[ -z "$FUCHSIA_IPV4_ADDR" ]]; then
+ fx-error "Can not determine IPV4 address of Fuchsia target"
+ exit 1
+fi
+
+export FUCHSIA_SSH_KEY="${FUCHSIA_DIR}/.ssh/pkey"
+
+export FUCHSIA_TEST_OUTDIR="${FUCHSIA_OUT_DIR}/test_out/$(date +'%F-%H:%M:%S')"
+mkdir -p "${FUCHSIA_TEST_OUTDIR}"
+
+"${FUCHSIA_BUILD_DIR}/host_x64/ermine_session_shell_test" "$@"