blob: 59b64f24a79304c9508b0471c688ecaa01effbb3 [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 launcher
import (
"context"
"time"
"chromiumos/tast/ctxutil"
"chromiumos/tast/errors"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/chrome/ash"
"chromiumos/tast/local/chrome/uiauto"
"chromiumos/tast/local/chrome/uiauto/cws"
"chromiumos/tast/local/chrome/uiauto/faillog"
"chromiumos/tast/local/chrome/uiauto/launcher"
"chromiumos/tast/local/chrome/uiauto/ossettings"
"chromiumos/tast/local/input"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
func init() {
testing.AddTest(&testing.Test{
Func: SearchInstalledApps,
LacrosStatus: testing.LacrosVariantUnneeded,
Desc: "Install apps from CWS and verify that it appears in the launcher",
Contacts: []string{
"kyle.chen@cienet.com",
"cienet-development@googlegroups.com",
"chromeos-sw-engprod@google.com",
},
Attr: []string{"group:mainline", "informational"},
SoftwareDeps: []string{"chrome"},
Timeout: 3*time.Minute + cws.InstallationTimeout,
Params: []testing.Param{{
Name: "productivity_launcher_clamshell_mode",
Val: launcher.TestCase{ProductivityLauncher: true, TabletMode: false},
Fixture: "chromeLoggedInWithGaiaProductivityLauncher",
}, {
Name: "clamshell_mode",
Val: launcher.TestCase{ProductivityLauncher: false, TabletMode: false},
Fixture: "chromeLoggedInWithGaiaLegacyLauncher",
}, {
Name: "productivity_launcher_tablet_mode",
Val: launcher.TestCase{ProductivityLauncher: true, TabletMode: true},
Fixture: "chromeLoggedInWithGaiaProductivityLauncher",
ExtraHardwareDeps: hwdep.D(hwdep.InternalDisplay()),
}, {
Name: "tablet_mode",
Val: launcher.TestCase{ProductivityLauncher: false, TabletMode: true},
Fixture: "chromeLoggedInWithGaiaLegacyLauncher",
ExtraHardwareDeps: hwdep.D(hwdep.InternalDisplay()),
}},
})
}
// SearchInstalledApps tests that apps installed from CWS appear in launcher.
func SearchInstalledApps(ctx context.Context, s *testing.State) {
cleanupCtx := ctx
ctx, cancel := ctxutil.Shorten(ctx, 10*time.Second)
defer cancel()
cr := s.FixtValue().(*chrome.Chrome)
tconn, err := cr.TestAPIConn(ctx)
if err != nil {
s.Fatal("Failed to create Test API connection: ", err)
}
ui := uiauto.New(tconn)
kw, err := input.Keyboard(ctx)
if err != nil {
s.Fatal("Failed to get keyboard: ", err)
}
defer kw.Close()
testCase := s.Param().(launcher.TestCase)
tabletMode := testCase.TabletMode
if !tabletMode {
defer func(ctx context.Context) {
if err := ui.RetryUntil(
kw.AccelAction("esc"),
func(ctx context.Context) error { return ash.WaitForLauncherState(ctx, tconn, ash.Closed) },
)(ctx); err != nil {
testing.ContextLog(ctx, "Failed to dismiss launcher: ", err)
}
}(cleanupCtx)
}
cleanup, err := ash.EnsureTabletModeEnabled(ctx, tconn, tabletMode)
if err != nil {
s.Fatal("Failed to ensure clamshell/tablet mode: ", err)
}
defer cleanup(cleanupCtx)
// When a DUT switches from tablet mode to clamshell mode, sometimes it takes a while to settle down.
if !tabletMode {
if err := ash.WaitForLauncherState(ctx, tconn, ash.Closed); err != nil {
s.Fatal("Launcher not closed after transition to clamshell mode: ", err)
}
}
cwsapp := newCwsAppGoogleDrawings(cr, tconn)
if err := cwsapp.install(ctx); err != nil {
s.Fatal("Failed to install an app from Chrome Web Store: ", err)
}
defer cwsapp.uninstall(cleanupCtx)
if err := uiauto.Combine("open Launcher and verify the app appears in search result",
launcher.Open(tconn),
launcher.Search(tconn, kw, cwsapp.name),
func(ctx context.Context) error {
return ui.WaitUntilExists(launcher.CreateAppSearchFinder(ctx, tconn, cwsapp.name))(ctx)
},
)(ctx); err != nil {
s.Fatal("Failed to verify that the app is in Launcher: ", err)
}
defer func(ctx context.Context) {
faillog.SaveScreenshotOnError(ctx, cr, s.OutDir(), s.HasError)
faillog.DumpUITreeOnError(ctx, s.OutDir(), s.HasError, tconn)
}(cleanupCtx)
}
// cwsAppGoogleDrawings defines the cws-app `Google Drawings`.
type cwsAppGoogleDrawings struct {
cr *chrome.Chrome
tconn *chrome.TestConn
id string
name string
cwsURL string
app *cws.App
}
// newCwsAppGoogleDrawings returns the instance of cwsAppGoogleDrawings.
func newCwsAppGoogleDrawings(cr *chrome.Chrome, tconn *chrome.TestConn) *cwsAppGoogleDrawings {
const (
id = "mkaakpdehdafacodkgkpghoibnmamcme"
name = "Google Drawings"
url = "https://chrome.google.com/webstore/detail/google-drawings/mkaakpdehdafacodkgkpghoibnmamcme"
)
return &cwsAppGoogleDrawings{
cr: cr,
tconn: tconn,
id: id,
name: name,
cwsURL: url,
app: &cws.App{Name: name, URL: url},
}
}
// install installs the cws-app via Chrome web store.
func (c *cwsAppGoogleDrawings) install(ctx context.Context) error {
isInstalled, err := ash.ChromeAppInstalled(ctx, c.tconn, c.id)
if err != nil {
return errors.Wrap(err, "failed to check CWS app's existance")
}
if isInstalled {
return nil
}
testing.ContextLogf(ctx, "Install CWS app: %q", c.name)
return cws.InstallApp(ctx, c.cr, c.tconn, *c.app)
}
// uninstall uninstalls the cws-app via ossettings.
func (c *cwsAppGoogleDrawings) uninstall(ctx context.Context) error {
isInstalled, err := ash.ChromeAppInstalled(ctx, c.tconn, c.id)
if err != nil {
return errors.Wrap(err, "failed to check CWS app's existance")
}
if !isInstalled {
return nil
}
defer func() {
settings := ossettings.New(c.tconn)
settings.Close(ctx)
}()
testing.ContextLogf(ctx, "Uninstall CWS app: %q", c.name)
return ossettings.UninstallApp(ctx, c.tconn, c.cr, c.name, c.id)
}