blob: f4147e41ddf50b42c31bc7deb5a364fcf2034394 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package network
import (
"context"
"time"
"chromiumos/tast/errors"
"chromiumos/tast/local/android/ui"
"chromiumos/tast/local/arc"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/network/systemproxy"
"chromiumos/tast/testing"
)
// RunArcConnectivityApp tests ARC++ app connectivity through the system-proxy Chrome OS daemon using the following steps:
// - installs a test ARC++ app;
// - connects to `url` in the app;
// - clicks on the system-proxy notification which informs the user that system-proxy requires credentials;
// - enters proxy credentials in the system-proxy dialog;
// - reads the network request's HTTP response code.
// In case of success it returns the global proxy. If the app fails to connect to the url or if the test fails, it returns an error.
// Note: If you require additional network configurations info for your test, please add the info to the ArcConnectivityTest app.
func RunArcConnectivityApp(ctx context.Context, a *arc.ARC, tconn *chrome.TestConn, url string, useSystemProxy bool, username, password string) (string, error) {
const (
pkg = "org.chromium.arc.testapp.connectivity"
activity = ".ConnectivityActivity"
// UI IDs in the app.
idPrefix = pkg + ":id/"
urlID = idPrefix + "url"
proxyID = idPrefix + "global_proxy"
fetchButtonID = idPrefix + "network_request_button"
waitButtonID = idPrefix + "await_result_button"
resultID = idPrefix + "result"
errorID = idPrefix + "error"
)
testing.ContextLog(ctx, "Installing ARC test app")
if err := a.Install(ctx, arc.APKPath("ArcConnectivityTest.apk")); err != nil {
return "", errors.Wrap(err, "failed to install app")
}
d, err := a.NewUIDevice(ctx)
if err != nil {
return "", errors.Wrap(err, "failed initializing UI Automator")
}
defer d.Close(ctx)
act, err := arc.NewActivity(a, pkg, pkg+activity)
if err != nil {
return "", errors.Wrap(err, "failed to create a new activity")
}
defer act.Close()
if err := act.Start(ctx, tconn); err != nil {
return "", errors.Wrap(err, "failed to start activity")
}
defer act.Stop(ctx, tconn)
// Read the global proxy which is displayed on the test app's UI.
field := d.Object(ui.ID(proxyID))
if err := field.WaitForExists(ctx, 30*time.Second); err != nil {
return "", errors.Wrap(err, "failed to find field")
}
proxy, err := field.GetText(ctx)
if err != nil {
return proxy, errors.Wrap(err, "failed to read global proxy value")
}
field = d.Object(ui.ID(urlID))
if err := field.WaitForExists(ctx, 30*time.Second); err != nil {
return proxy, errors.Wrap(err, "failed to find field")
}
if err := field.SetText(ctx, url); err != nil {
return proxy, errors.Wrap(err, "failed to set url")
}
// Do network request.
field = d.Object(ui.ID(fetchButtonID))
if err := field.WaitForExists(ctx, 30*time.Second); err != nil {
return proxy, errors.Wrap(err, "failed to find field")
}
if err := field.Click(ctx); err != nil {
return proxy, errors.Wrap(err, "failed to click field")
}
if useSystemProxy {
// Wait for the system-proxy daemon to ask for proxy credentials and authenticate in the system dialog.
if err := systemproxy.DoSystemProxyAuthentication(ctx, tconn, username, password); err != nil {
return proxy, errors.Wrap(err, "system-proxy authentication failed")
}
}
field = d.Object(ui.ID(waitButtonID))
if err := field.WaitForExists(ctx, 30*time.Second); err != nil {
return proxy, errors.Wrap(err, "failed to find field")
}
// Wait for the network request result.
if err := field.Click(ctx); err != nil {
return proxy, errors.Wrap(err, "failed to click field")
}
const httpOk = "200"
field = d.Object(ui.ID(resultID))
if err := field.WaitForText(ctx, httpOk, 30*time.Second); err != nil {
// If there was a networking error displayed in the app, return it instead of the initial error.
netErr := func() string {
field = d.Object(ui.ID(errorID))
if e := field.WaitForExists(ctx, 30*time.Second); e != nil {
return ""
}
text, _ := field.GetText(ctx)
return text
}()
if netErr != "" {
// Return the network error from the app.
return proxy, errors.Wrapf(err, "app reported network error %s", netErr)
}
// Return the initial error.
return proxy, errors.Wrap(err, "fail wait for text")
}
return proxy, nil
}