blob: a894d8312315ca5f95c7ee73bf2e30b88f3bc277 [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 arc
import (
"context"
"path/filepath"
"time"
"chromiumos/tast/common/testexec"
"chromiumos/tast/errors"
androidui "chromiumos/tast/local/android/ui"
"chromiumos/tast/local/apps"
"chromiumos/tast/local/arc"
"chromiumos/tast/local/arc/optin"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/chrome/ash"
"chromiumos/tast/local/chrome/uiauto"
"chromiumos/tast/local/chrome/uiauto/faillog"
"chromiumos/tast/local/chrome/uiauto/nodewith"
"chromiumos/tast/local/chrome/uiauto/role"
"chromiumos/tast/testing"
)
const appVersiontimeoutUI = 30 * time.Second
func init() {
testing.AddTest(&testing.Test{
Func: AppVersion,
Desc: "Verifies that app version is available from app info page",
Contacts: []string{"vkrishan@google.com", "cros-arc-te@google.com"},
Attr: []string{"group:mainline", "informational", "group:arc-functional"},
SoftwareDeps: []string{"chrome"},
Params: []testing.Param{{
ExtraSoftwareDeps: []string{"android_p"},
}, {
Name: "vm",
ExtraSoftwareDeps: []string{"android_vm"},
}},
Timeout: chrome.GAIALoginTimeout + arc.BootTimeout + 120*time.Second,
VarDeps: []string{"ui.gaiaPoolDefault"},
})
}
func AppVersion(ctx context.Context, s *testing.State) {
cr, err := chrome.New(ctx,
chrome.GAIALoginPool(s.RequiredVar("ui.gaiaPoolDefault")),
chrome.ARCSupported(),
chrome.ExtraArgs(arc.DisableSyncFlags()...))
if err != nil {
s.Fatal("Failed to start Chrome: ", err)
}
defer cr.Close(ctx)
tconn, err := cr.TestAPIConn(ctx)
if err != nil {
s.Fatal("Failed to connect Test API: ", err)
}
defer faillog.DumpUITreeOnError(ctx, s.OutDir(), s.HasError, tconn)
// Optin to PlayStore and Close.
if err := optin.PerformAndClose(ctx, cr, tconn); err != nil {
s.Fatal("Failed to optin to Play Store and Close: ", err)
}
// Setup ARC.
a, err := arc.New(ctx, s.OutDir())
if err != nil {
s.Fatal("Failed connecing to ARC: ", err)
}
defer a.Close(ctx)
defer func() {
if s.HasError() {
if err := a.Command(ctx, "uiautomator", "dump").Run(testexec.DumpLogOnError); err != nil {
s.Error("Failed to dump UIAutomator: ", err)
} else if err := a.PullFile(ctx, "/sdcard/window_dump.xml",
filepath.Join(s.OutDir(), "uiautomator_dump.xml")); err != nil {
s.Error("Failed to pull UIAutomator dump: ", err)
}
}
}()
d, err := a.NewUIDevice(ctx)
if err != nil {
s.Fatal("Failed initializing UI Automator: ", err)
}
defer d.Close(ctx)
if err := openAppInfoPage(ctx, tconn); err != nil {
s.Fatal("Failed to open app info page: ", err)
}
if err := verifyAppVersion(ctx, d, tconn); err != nil {
s.Fatal("Failed verifying app Version: ", err)
}
}
// openAppInfoPage opens app info page of PlayStore.
func openAppInfoPage(ctx context.Context, tconn *chrome.TestConn) error {
// Open App info page by right click on Play Store App.
settings := nodewith.Name("Settings").Role(role.Window).First()
playstoreSubpage := "Play Store subpage back button"
ui := uiauto.New(tconn)
playstoreSubpageButton := nodewith.Name(playstoreSubpage).Role(role.Button).Ancestor(settings)
appInfoMenu := nodewith.Name("App info").Role(role.MenuItem)
openPlayStoreAppInfoPage := func() uiauto.Action {
return uiauto.Combine("check app context menu and settings",
ui.LeftClick(appInfoMenu),
ui.WaitUntilExists(playstoreSubpageButton))
}
moreSettingsButton := nodewith.Name("More settings and permissions").Role(role.Link)
if err := uiauto.Combine("check context menu of play store app on the shelf",
ash.RightClickApp(tconn, apps.PlayStore.Name),
openPlayStoreAppInfoPage(),
ui.LeftClick(moreSettingsButton))(ctx); err != nil {
return errors.Wrap(err, "failed to open app info for Play Store app")
}
return nil
}
// verifyAppVersion check that version is present in app info page under Advanced.
func verifyAppVersion(ctx context.Context, d *androidui.Device,
tconn *chrome.TestConn) error {
// Click on Advanced to expand it.
advancedSettings := d.Object(androidui.ClassName("android.widget.TextView"), androidui.TextMatches("(?i)Advanced"), androidui.Enabled(true))
if err := advancedSettings.WaitForExists(ctx, appVersiontimeoutUI); err != nil {
return errors.Wrap(err, "failed to find Advanced")
}
if err := advancedSettings.Click(ctx); err != nil {
return errors.Wrap(err, "failed to click Advanced")
}
// Scroll until the version is displayed.
scrollLayout := d.Object(androidui.ClassName("android.support.v7.widget.RecyclerView"), androidui.Scrollable(true))
if t, ok := arc.Type(); ok && t == arc.VM {
scrollLayout = d.Object(androidui.ClassName("androidx.recyclerview.widget.RecyclerView"), androidui.Scrollable(true))
}
system := d.Object(androidui.ClassName("android.widget.TextView"), androidui.TextContains("(?i)Modify system settings"), androidui.Enabled(true))
if err := scrollLayout.WaitForExists(ctx, appVersiontimeoutUI); err == nil {
scrollLayout.ScrollTo(ctx, system)
}
// Verify version is not empty.
versionText, err := d.Object(androidui.ID("android:id/summary"), androidui.TextStartsWith("version")).GetText(ctx)
if err != nil {
return errors.Wrap(err, "failed to ger version")
}
if len(versionText) == 0 {
return errors.Wrap(err, "version is empty")
}
testing.ContextLogf(ctx, "App Version = %s", versionText)
return nil
}