blob: 09d4f71b99a54e3bbcf20cef13551b61b3537aa2 [file]
// 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 loginapi
import (
"context"
"fmt"
"time"
"chromiumos/tast/common/fixture"
"chromiumos/tast/common/policy"
"chromiumos/tast/common/policy/fakedms"
"chromiumos/tast/ctxutil"
"chromiumos/tast/local/chrome"
"chromiumos/tast/local/mgs"
"chromiumos/tast/local/policyutil"
"chromiumos/tast/local/policyutil/fixtures"
"chromiumos/tast/testing"
)
func init() {
testing.AddTest(&testing.Test{
Func: LoginScreenUIAPI,
LacrosStatus: testing.LacrosVariantUnneeded,
Desc: "Test chrome.loginScreenUi Extension API",
Contacts: []string{
"jityao@google.com", // Test author
"chromeos-commercial-identity@google.com",
},
Attr: []string{"group:mainline", "informational"},
SoftwareDeps: []string{"chrome"},
Fixture: fixture.FakeDMSEnrolled,
})
}
func LoginScreenUIAPI(ctx context.Context, s *testing.State) {
fdms := s.FixtValue().(*fakedms.FakeDMS)
// Start a Chrome instance that will fetch policies from the FakeDMS.
cr, err := chrome.New(ctx,
chrome.FakeLogin(chrome.Creds{User: fixtures.Username, Pass: fixtures.Password}),
chrome.DMSPolicy(fdms.URL),
chrome.KeepEnrollment())
if err != nil {
s.Fatal("Chrome login failed: ", err)
}
defer func(ctx context.Context) {
// Use cr as a reference to close the last started Chrome instance.
if err := cr.Close(ctx); err != nil {
s.Error("Failed to close Chrome connection: ", err)
}
}(ctx)
// Use a shortened context for test operations to reserve time for cleanup.
ctx, cancel := ctxutil.Shorten(ctx, 30*time.Second)
defer cancel()
policies := []policy.Policy{
&policy.DeviceLoginScreenExtensions{
Val: []string{mgs.LoginScreenExtensionID},
},
}
if err := policyutil.ServeAndRefresh(ctx, fdms, cr, policies); err != nil {
s.Fatal("Failed to serve policies: ", err)
}
// Close the previous Chrome instance.
if err := cr.Close(ctx); err != nil {
s.Fatal("Failed to close Chrome connection: ", err)
}
// Restart Chrome, forcing Devtools to be available on the login screen.
cr, err = chrome.New(ctx,
chrome.NoLogin(),
chrome.DMSPolicy(fdms.URL),
chrome.KeepEnrollment(),
chrome.ExtraArgs("--force-devtools-available"))
if err != nil {
s.Fatal("Chrome restart failed: ", err)
}
loginScreenBGURL := chrome.ExtensionBackgroundPageURL(mgs.LoginScreenExtensionID)
bgConn, err := cr.NewConnForTarget(ctx, chrome.MatchTargetURL(loginScreenBGURL))
if err != nil {
s.Fatal("Failed to connect to login screen background page: ", err)
}
defer bgConn.Close()
// Show window.html.
// The file window.html is bundled with the extension.
if err := bgConn.Eval(ctx, `new Promise((resolve, reject) => {
chrome.loginScreenUi.show({url: "window.html"}, () => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
return;
}
resolve();
});
})`, nil); err != nil {
s.Fatal("Failed to show window: ", err)
}
windowURL := fmt.Sprintf("chrome-extension://%s/window.html", mgs.LoginScreenExtensionID)
windowConn, err := cr.NewConnForTarget(ctx, chrome.MatchTargetURL(windowURL))
if err != nil {
s.Fatal("Failed to connect to window: ", err)
}
defer windowConn.Close()
windowCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()
// Check that the window title is correct.
// WaitForExpr has to be used since the window title is not updated immediately.
expectedWindowTitle := "Login screen APIs test extension"
expr := fmt.Sprintf(`document.querySelector('title').innerText === '%s'`, expectedWindowTitle)
if err := windowConn.WaitForExpr(windowCtx, expr); err != nil {
s.Error("Window title does not match: ", err)
}
// Close the window.
if err := bgConn.Eval(ctx, `new Promise((resolve, reject) => {
chrome.loginScreenUi.close(() => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
return;
}
resolve();
});
})`, nil); err != nil {
s.Fatal("Failed to close window: ", err)
}
// Check that the window is closed.
available, err := cr.IsTargetAvailable(ctx, chrome.MatchTargetURL(windowURL))
if err != nil {
s.Fatal("Failed to get targets: ", err)
}
if available {
s.Error("Window was not closed")
}
}