| // Copyright 2022 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package ui |
| |
| import ( |
| "context" |
| "fmt" |
| "path/filepath" |
| "time" |
| |
| "github.com/golang/protobuf/ptypes/empty" |
| "google.golang.org/grpc" |
| |
| "go.chromium.org/tast-tests/cros/remote/crosserverutil" |
| pb "go.chromium.org/tast-tests/cros/services/cros/ui" |
| "go.chromium.org/tast/core/testing" |
| ) |
| |
| func init() { |
| testing.AddTest(&testing.Test{ |
| Func: ScreenRecorderServiceGRPC, |
| LacrosStatus: testing.LacrosVariantUnneeded, |
| Desc: "Check basic functionalities of ScreenRecorderService", |
| Contacts: []string{"chromeos-sw-engprod@google.com", "jonfan@google.com"}, |
| BugComponent: "b:1034649", |
| Attr: []string{"group:mainline", "informational", "group:hw_agnostic"}, |
| SoftwareDeps: []string{"chrome"}, |
| Params: []testing.Param{{ |
| Name: "given_path", |
| Val: "record.webm", |
| }, { |
| Name: "temp_path", |
| Val: "", |
| }}, |
| }) |
| } |
| |
| func ScreenRecorderServiceGRPC(ctx context.Context, s *testing.State) { |
| cl, err := crosserverutil.GetGRPCClient(ctx, s.DUT()) |
| if err != nil { |
| s.Fatal("Failed to connect to the RPC service on the DUT: ", err) |
| } |
| defer cl.Close(ctx) |
| |
| fileName := s.Param().(string) |
| if fileName != "" { |
| // Append test output directory to file name |
| fileName = filepath.Join(s.OutDir(), fileName) |
| } |
| verifyScreenRecording(ctx, cl.Conn, fileName, s) |
| } |
| |
| func verifyScreenRecording(ctx context.Context, conn *grpc.ClientConn, fileName string, s *testing.State) { |
| // Make a screen recording |
| actualFileName := makeScreenRecording(ctx, conn, fileName, s) |
| |
| // verify if the file is saved in the desired path |
| if fileName != "" && fileName != actualFileName { |
| s.Fatalf("Requested file name and actual file name mismatch. requested: %v actual: %v ", fileName, actualFileName) |
| } |
| |
| //Verify that screen recording is on the file system |
| if _, err := s.DUT().Conn().CommandContext(ctx, "[", "-e", actualFileName, "]").CombinedOutput(); err != nil { |
| s.Fatal(fmt.Sprintf("Failed to find recording: %v", fileName), err) |
| } |
| } |
| |
| func makeScreenRecording(ctx context.Context, conn *grpc.ClientConn, fileName string, s *testing.State) string { |
| // Start Chrome on the DUT. |
| cs := pb.NewChromeServiceClient(conn) |
| loginReq := &pb.NewRequest{} |
| if _, err := cs.New(ctx, loginReq, grpc.WaitForReady(true)); err != nil { |
| s.Fatal("Failed to start Chrome: ", err) |
| } |
| defer cs.Close(ctx, &empty.Empty{}) |
| |
| // Start Recording |
| recorderSvc := pb.NewScreenRecorderServiceClient(conn) |
| req := &pb.StartRequest{FileName: fileName} |
| if _, err := recorderSvc.Start(ctx, req); err != nil { |
| s.Fatal("Failed to start screen recording: ", err) |
| } |
| // Verify that Start correctly return an error when there is already a recording in progress |
| if _, err := recorderSvc.Start(ctx, req); err == nil { |
| s.Fatal("should return an error calling Start() when there is a recording in process: ", err) |
| } |
| |
| // Performs some actions on the UI like Opening Files App |
| uiautoSvc := pb.NewAutomationServiceClient(conn) |
| filesAppShelfButtonFinder := &pb.Finder{ |
| NodeWiths: []*pb.NodeWith{ |
| {Value: &pb.NodeWith_HasClass{HasClass: "ShelfAppButton"}}, |
| {Value: &pb.NodeWith_Name{Name: "Files"}}, |
| }, |
| } |
| if _, err := uiautoSvc.WaitUntilExists(ctx, &pb.WaitUntilExistsRequest{Finder: filesAppShelfButtonFinder}); err != nil { |
| s.Fatal("Failed to find Files shelf button: ", err) |
| } |
| if _, err := uiautoSvc.LeftClick(ctx, &pb.LeftClickRequest{Finder: filesAppShelfButtonFinder}); err != nil { |
| s.Fatal("Failed to click on Files app: ", err) |
| } |
| testing.Sleep(ctx, time.Second) |
| |
| // Stopping and saving screen recording |
| resp, err := recorderSvc.Stop(ctx, &empty.Empty{}) |
| if err != nil { |
| s.Fatal("Failed to stop and save recording: ", err) |
| } |
| // Verify that StopSaveRelease returns an error when this is no recording in progress |
| if _, err := recorderSvc.Stop(ctx, &empty.Empty{}); err == nil { |
| s.Fatal("should return an error when there is no recording in process") |
| } |
| |
| return resp.FileName |
| } |