github.com/MontFerret/ferret@v0.18.0/pkg/drivers/cdp/input/manager.go (about) 1 package input 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/mafredri/cdp" 8 "github.com/mafredri/cdp/protocol/dom" 9 "github.com/mafredri/cdp/protocol/runtime" 10 "github.com/rs/zerolog" 11 12 "github.com/MontFerret/ferret/pkg/drivers" 13 "github.com/MontFerret/ferret/pkg/drivers/cdp/eval" 14 "github.com/MontFerret/ferret/pkg/drivers/cdp/templates" 15 "github.com/MontFerret/ferret/pkg/runtime/core" 16 "github.com/MontFerret/ferret/pkg/runtime/logging" 17 "github.com/MontFerret/ferret/pkg/runtime/values" 18 ) 19 20 type ( 21 TypeParams struct { 22 Text string 23 Clear bool 24 Delay time.Duration 25 } 26 27 Manager struct { 28 logger zerolog.Logger 29 client *cdp.Client 30 exec *eval.Runtime 31 keyboard *Keyboard 32 mouse *Mouse 33 } 34 ) 35 36 func New( 37 logger zerolog.Logger, 38 client *cdp.Client, 39 exec *eval.Runtime, 40 keyboard *Keyboard, 41 mouse *Mouse, 42 ) *Manager { 43 logger = logging.WithName(logger.With(), "input_manager").Logger() 44 45 return &Manager{ 46 logger, 47 client, 48 exec, 49 keyboard, 50 mouse, 51 } 52 } 53 54 func (m *Manager) Keyboard() *Keyboard { 55 return m.keyboard 56 } 57 58 func (m *Manager) Mouse() *Mouse { 59 return m.mouse 60 } 61 62 func (m *Manager) ScrollTop(ctx context.Context, options drivers.ScrollOptions) error { 63 m.logger.Trace(). 64 Str("behavior", options.Behavior.String()). 65 Str("block", options.Block.String()). 66 Str("inline", options.Inline.String()). 67 Msg("scrolling to the top") 68 69 if err := m.exec.Eval(ctx, templates.ScrollTop(options)); err != nil { 70 m.logger.Trace().Err(err).Msg("failed to scroll to the top") 71 72 return err 73 } 74 75 m.logger.Trace().Msg("scrolled to the top") 76 77 return nil 78 } 79 80 func (m *Manager) ScrollBottom(ctx context.Context, options drivers.ScrollOptions) error { 81 m.logger.Trace(). 82 Str("behavior", options.Behavior.String()). 83 Str("block", options.Block.String()). 84 Str("inline", options.Inline.String()). 85 Msg("scrolling to the bottom") 86 87 if err := m.exec.Eval(ctx, templates.ScrollBottom(options)); err != nil { 88 m.logger.Trace().Err(err).Msg("failed to scroll to the bottom") 89 90 return err 91 } 92 93 m.logger.Trace().Msg("scrolled to the bottom") 94 95 return nil 96 } 97 98 func (m *Manager) ScrollIntoView(ctx context.Context, id runtime.RemoteObjectID, options drivers.ScrollOptions) error { 99 m.logger.Trace(). 100 Str("object_id", string(id)). 101 Str("behavior", options.Behavior.String()). 102 Str("block", options.Block.String()). 103 Str("inline", options.Inline.String()). 104 Msg("scrolling to an element") 105 106 if err := m.exec.Eval(ctx, templates.ScrollIntoView(id, options)); err != nil { 107 m.logger.Trace().Err(err).Msg("failed to scroll to an element") 108 109 return err 110 } 111 112 m.logger.Trace().Msg("scrolled to an element") 113 114 return nil 115 } 116 117 func (m *Manager) ScrollIntoViewBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector, options drivers.ScrollOptions) error { 118 m.logger.Trace(). 119 Str("selector", selector.String()). 120 Str("behavior", options.Behavior.String()). 121 Str("block", options.Block.String()). 122 Str("inline", options.Inline.String()). 123 Msg("scrolling to an element by selector") 124 125 if err := m.exec.Eval(ctx, templates.ScrollIntoViewBySelector(id, selector, options)); err != nil { 126 m.logger.Trace().Err(err).Msg("failed to scroll to an element by selector") 127 128 return err 129 } 130 131 m.logger.Trace().Msg("scrolled to an element by selector") 132 133 return nil 134 } 135 136 func (m *Manager) ScrollByXY(ctx context.Context, options drivers.ScrollOptions) error { 137 m.logger.Trace(). 138 Float64("x", float64(options.Top)). 139 Float64("y", float64(options.Left)). 140 Str("behavior", options.Behavior.String()). 141 Str("block", options.Block.String()). 142 Str("inline", options.Inline.String()). 143 Msg("scrolling to an element by given coordinates") 144 145 if err := m.exec.Eval(ctx, templates.Scroll(options)); err != nil { 146 m.logger.Trace().Err(err).Msg("failed to scroll to an element by coordinates") 147 148 return err 149 } 150 151 m.logger.Trace().Msg("scrolled to an element by given coordinates") 152 153 return nil 154 } 155 156 func (m *Manager) Focus(ctx context.Context, objectID runtime.RemoteObjectID) error { 157 m.logger.Trace(). 158 Str("object_id", string(objectID)). 159 Msg("focusing on an element") 160 161 err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{ 162 Behavior: drivers.ScrollBehaviorAuto, 163 Block: drivers.ScrollVerticalAlignmentCenter, 164 Inline: drivers.ScrollHorizontalAlignmentCenter, 165 }) 166 167 if err != nil { 168 return err 169 } 170 171 if err := m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(objectID)); err != nil { 172 m.logger.Trace().Err(err).Msg("failed focusing on an element") 173 174 return err 175 } 176 177 m.logger.Trace().Msg("focused on an element") 178 179 return nil 180 } 181 182 func (m *Manager) FocusBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector) error { 183 m.logger.Trace(). 184 Str("parent_object_id", string(id)). 185 Str("selector", selector.String()). 186 Msg("focusing on an element by selector") 187 188 err := m.ScrollIntoViewBySelector(ctx, id, selector, drivers.ScrollOptions{ 189 Behavior: drivers.ScrollBehaviorAuto, 190 Block: drivers.ScrollVerticalAlignmentCenter, 191 Inline: drivers.ScrollHorizontalAlignmentCenter, 192 }) 193 194 if err != nil { 195 return err 196 } 197 198 m.logger.Trace().Msg("resolving an element by selector") 199 200 found, err := m.exec.EvalRef(ctx, templates.QuerySelector(id, selector)) 201 202 if err != nil { 203 m.logger.Trace(). 204 Err(err). 205 Msg("failed resolving an element by selector") 206 207 return err 208 } 209 210 if found.ObjectID == nil { 211 m.logger.Trace(). 212 Err(core.ErrNotFound). 213 Msg("element not found by selector") 214 215 return core.ErrNotFound 216 } 217 218 if err := m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(*found.ObjectID)); err != nil { 219 m.logger.Trace(). 220 Err(err). 221 Msg("failed focusing on an element by selector") 222 223 return err 224 } 225 226 m.logger.Trace().Msg("focused on an element") 227 228 return nil 229 } 230 231 func (m *Manager) Blur(ctx context.Context, objectID runtime.RemoteObjectID) error { 232 m.logger.Trace(). 233 Str("object_id", string(objectID)). 234 Msg("removing focus from an element") 235 236 if err := m.exec.Eval(ctx, templates.Blur(objectID)); err != nil { 237 m.logger.Trace(). 238 Err(err). 239 Msg("failed removing focus from an element") 240 241 return err 242 } 243 244 m.logger.Trace().Msg("removed focus from an element") 245 246 return nil 247 } 248 249 func (m *Manager) BlurBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector) error { 250 m.logger.Trace(). 251 Str("parent_object_id", string(id)). 252 Str("selector", selector.String()). 253 Msg("removing focus from an element by selector") 254 255 if err := m.exec.Eval(ctx, templates.BlurBySelector(id, selector)); err != nil { 256 m.logger.Trace(). 257 Err(err). 258 Msg("failed removing focus from an element by selector") 259 260 return err 261 } 262 263 m.logger.Trace().Msg("removed focus from an element by selector") 264 265 return nil 266 } 267 268 func (m *Manager) MoveMouse(ctx context.Context, objectID runtime.RemoteObjectID) error { 269 m.logger.Trace(). 270 Str("object_id", string(objectID)). 271 Msg("starting to move the mouse towards an element") 272 273 if err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{}); err != nil { 274 m.logger.Trace().Err(err).Msg("could not scroll into the object. failed to move the mouse") 275 276 return err 277 } 278 279 m.logger.Trace().Msg("calculating clickable element points") 280 281 q, err := GetClickablePointByObjectID(ctx, m.client, objectID) 282 283 if err != nil { 284 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 285 286 return err 287 } 288 289 m.logger.Trace().Float64("x", q.X).Float64("y", q.Y).Msg("calculated clickable element points") 290 291 if err := m.mouse.Move(ctx, q.X, q.Y); err != nil { 292 m.logger.Trace().Err(err).Msg("failed to move the mouse") 293 294 return err 295 } 296 297 m.logger.Trace().Msg("moved the mouse") 298 299 return nil 300 } 301 302 func (m *Manager) MoveMouseBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector) error { 303 m.logger.Trace(). 304 Str("parent_object_id", string(id)). 305 Str("selector", selector.String()). 306 Msg("starting to move the mouse towards an element by selector") 307 308 if err := m.ScrollIntoViewBySelector(ctx, id, selector, drivers.ScrollOptions{}); err != nil { 309 return err 310 } 311 312 m.logger.Trace().Msg("looking up for an element by selector") 313 314 found, err := m.exec.EvalRef(ctx, templates.QuerySelector(id, selector)) 315 316 if err != nil { 317 m.logger.Trace().Err(err).Msg("failed to find an element by selector") 318 319 return err 320 } 321 322 if found.ObjectID == nil { 323 m.logger.Trace(). 324 Err(core.ErrNotFound). 325 Msg("element not found by selector") 326 327 return core.ErrNotFound 328 } 329 330 m.logger.Trace().Str("object_id", string(*found.ObjectID)).Msg("calculating clickable element points") 331 332 points, err := GetClickablePointByObjectID(ctx, m.client, *found.ObjectID) 333 334 if err != nil { 335 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 336 337 return err 338 } 339 340 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 341 342 if err := m.mouse.Move(ctx, points.X, points.Y); err != nil { 343 m.logger.Trace().Err(err).Msg("failed to move the mouse") 344 345 return err 346 } 347 348 m.logger.Trace().Msg("moved the mouse") 349 350 return nil 351 } 352 353 func (m *Manager) MoveMouseByXY(ctx context.Context, xv, yv values.Float) error { 354 x := float64(xv) 355 y := float64(yv) 356 357 m.logger.Trace(). 358 Float64("x", x). 359 Float64("y", y). 360 Msg("starting to move the mouse towards an element by given coordinates") 361 362 if err := m.ScrollByXY(ctx, drivers.ScrollOptions{ 363 Top: xv, 364 Left: yv, 365 }); err != nil { 366 return err 367 } 368 369 if err := m.mouse.Move(ctx, x, y); err != nil { 370 m.logger.Trace().Err(err).Msg("failed to move the mouse towards an element by given coordinates") 371 372 return err 373 } 374 375 m.logger.Trace().Msg("moved the mouse") 376 377 return nil 378 } 379 380 func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID, count int) error { 381 m.logger.Trace(). 382 Str("object_id", string(objectID)). 383 Msg("starting to click on an element") 384 385 if err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{ 386 Behavior: drivers.ScrollBehaviorAuto, 387 Block: drivers.ScrollVerticalAlignmentCenter, 388 Inline: drivers.ScrollHorizontalAlignmentCenter, 389 }); err != nil { 390 return err 391 } 392 393 m.logger.Trace().Msg("calculating clickable element points") 394 395 points, err := GetClickablePointByObjectID(ctx, m.client, objectID) 396 397 if err != nil { 398 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 399 400 return err 401 } 402 403 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 404 405 delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond 406 407 if err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, count); err != nil { 408 m.logger.Trace(). 409 Err(err). 410 Msg("failed to click on an element") 411 412 return err 413 } 414 415 m.logger.Trace(). 416 Err(err). 417 Msg("clicked on an element") 418 419 return nil 420 } 421 422 func (m *Manager) ClickBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector, count values.Int) error { 423 m.logger.Trace(). 424 Str("parent_object_id", string(id)). 425 Str("selector", selector.String()). 426 Int64("count", int64(count)). 427 Msg("clicking on an element by selector") 428 429 if err := m.ScrollIntoViewBySelector(ctx, id, selector, drivers.ScrollOptions{ 430 Behavior: drivers.ScrollBehaviorAuto, 431 Block: drivers.ScrollVerticalAlignmentCenter, 432 Inline: drivers.ScrollHorizontalAlignmentCenter, 433 }); err != nil { 434 return err 435 } 436 437 m.logger.Trace().Msg("looking up for an element by selector") 438 439 found, err := m.exec.EvalRef(ctx, templates.QuerySelector(id, selector)) 440 441 if err != nil { 442 m.logger.Trace().Err(err).Msg("failed to find an element by selector") 443 444 return err 445 } 446 447 if found.ObjectID == nil { 448 m.logger.Trace(). 449 Err(core.ErrNotFound). 450 Msg("element not found by selector") 451 452 return core.ErrNotFound 453 } 454 455 m.logger.Trace().Str("object_id", string(*found.ObjectID)).Msg("calculating clickable element points") 456 457 points, err := GetClickablePointByObjectID(ctx, m.client, *found.ObjectID) 458 459 if err != nil { 460 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 461 462 return err 463 } 464 465 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 466 467 delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond 468 469 if err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, int(count)); err != nil { 470 m.logger.Trace().Err(err).Msg("failed to click on an element") 471 return nil 472 } 473 474 m.logger.Trace().Msg("clicked on an element") 475 476 return nil 477 } 478 479 func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, params TypeParams) error { 480 m.logger.Trace(). 481 Str("object_id", string(objectID)). 482 Msg("starting to type text") 483 484 err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{ 485 Behavior: drivers.ScrollBehaviorAuto, 486 Block: drivers.ScrollVerticalAlignmentCenter, 487 Inline: drivers.ScrollHorizontalAlignmentCenter, 488 }) 489 490 if err != nil { 491 return err 492 } 493 494 m.logger.Trace().Msg("focusing on an element") 495 496 if err := m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(objectID)); err != nil { 497 m.logger.Trace().Msg("failed to focus on an element") 498 499 return err 500 } 501 502 m.logger.Trace().Bool("clear", params.Clear).Msg("is clearing text required?") 503 504 if params.Clear { 505 m.logger.Trace().Msg("calculating clickable element points") 506 507 points, err := GetClickablePointByObjectID(ctx, m.client, objectID) 508 509 if err != nil { 510 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 511 512 return err 513 } 514 515 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 516 517 if err := m.ClearByXY(ctx, points); err != nil { 518 return err 519 } 520 } 521 522 d := core.NumberLowerBoundary(float64(params.Delay)) 523 beforeTypeDelay := time.Duration(d) 524 525 m.logger.Trace().Float64("delay", d).Msg("calculated pause delay") 526 527 time.Sleep(beforeTypeDelay) 528 529 m.logger.Trace().Msg("starting to type text") 530 531 if err := m.keyboard.Type(ctx, params.Text, params.Delay); err != nil { 532 m.logger.Trace().Err(err).Msg("failed to type text") 533 534 return err 535 } 536 537 m.logger.Trace().Msg("typed text") 538 539 return nil 540 } 541 542 func (m *Manager) TypeBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector, params TypeParams) error { 543 m.logger.Trace(). 544 Str("parent_object_id", string(id)). 545 Str("selector", selector.String()). 546 Msg("starting to type text by selector") 547 548 err := m.ScrollIntoViewBySelector(ctx, id, selector, drivers.ScrollOptions{ 549 Behavior: drivers.ScrollBehaviorAuto, 550 Block: drivers.ScrollVerticalAlignmentCenter, 551 Inline: drivers.ScrollHorizontalAlignmentCenter, 552 }) 553 554 if err != nil { 555 return err 556 } 557 558 m.logger.Trace().Msg("looking up for an element by selector") 559 560 found, err := m.exec.EvalRef(ctx, templates.QuerySelector(id, selector)) 561 562 if err != nil { 563 m.logger.Trace().Err(err).Msg("failed to find an element by selector") 564 565 return err 566 } 567 568 if found.ObjectID == nil { 569 m.logger.Trace(). 570 Err(core.ErrNotFound). 571 Msg("element not found by selector") 572 573 return core.ErrNotFound 574 } 575 576 m.logger.Trace().Str("object_id", string(*found.ObjectID)).Msg("focusing on an element") 577 578 err = m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(*found.ObjectID)) 579 580 if err != nil { 581 m.logger.Trace().Err(err).Msg("failed to focus on an element") 582 583 return err 584 } 585 586 m.logger.Trace().Bool("clear", params.Clear).Msg("is clearing text required?") 587 588 if params.Clear { 589 m.logger.Trace().Msg("calculating clickable element points") 590 591 points, err := GetClickablePointByObjectID(ctx, m.client, *found.ObjectID) 592 593 if err != nil { 594 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 595 596 return err 597 } 598 599 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 600 601 if err := m.ClearByXY(ctx, points); err != nil { 602 return err 603 } 604 } 605 606 d := core.NumberLowerBoundary(float64(params.Delay)) 607 beforeTypeDelay := time.Duration(d) 608 609 m.logger.Trace().Float64("delay", d).Msg("calculated pause delay") 610 611 time.Sleep(beforeTypeDelay) 612 613 m.logger.Trace().Msg("starting to type text") 614 615 if err := m.keyboard.Type(ctx, params.Text, params.Delay); err != nil { 616 m.logger.Trace().Err(err).Msg("failed to type text") 617 618 return err 619 } 620 621 m.logger.Trace().Msg("typed text") 622 623 return nil 624 } 625 626 func (m *Manager) Clear(ctx context.Context, objectID runtime.RemoteObjectID) error { 627 m.logger.Trace(). 628 Str("object_id", string(objectID)). 629 Msg("starting to clear element") 630 631 err := m.ScrollIntoView(ctx, objectID, drivers.ScrollOptions{ 632 Behavior: drivers.ScrollBehaviorAuto, 633 Block: drivers.ScrollVerticalAlignmentCenter, 634 Inline: drivers.ScrollHorizontalAlignmentCenter, 635 }) 636 637 if err != nil { 638 return err 639 } 640 641 m.logger.Trace().Msg("calculating clickable element points") 642 643 points, err := GetClickablePointByObjectID(ctx, m.client, objectID) 644 645 if err != nil { 646 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 647 648 return err 649 } 650 651 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 652 m.logger.Trace().Msg("focusing on an element") 653 654 err = m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(objectID)) 655 656 if err != nil { 657 m.logger.Trace().Err(err).Msg("failed to focus on an element") 658 659 return err 660 } 661 662 m.logger.Trace().Msg("clearing element") 663 664 if err := m.ClearByXY(ctx, points); err != nil { 665 m.logger.Trace().Err(err).Msg("failed to clear element") 666 667 return err 668 } 669 670 m.logger.Trace().Msg("cleared element") 671 672 return nil 673 } 674 675 func (m *Manager) ClearBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector) error { 676 m.logger.Trace(). 677 Str("parent_object_id", string(id)). 678 Str("selector", selector.String()). 679 Msg("starting to clear element by selector") 680 681 err := m.ScrollIntoViewBySelector(ctx, id, selector, drivers.ScrollOptions{ 682 Behavior: drivers.ScrollBehaviorAuto, 683 Block: drivers.ScrollVerticalAlignmentCenter, 684 Inline: drivers.ScrollHorizontalAlignmentCenter, 685 }) 686 687 if err != nil { 688 return err 689 } 690 691 m.logger.Trace().Msg("looking up for an element by selector") 692 693 found, err := m.exec.EvalRef(ctx, templates.QuerySelector(id, selector)) 694 695 if err != nil { 696 m.logger.Trace().Err(err).Msg("failed to find an element by selector") 697 698 return err 699 } 700 701 if found.ObjectID == nil { 702 m.logger.Trace(). 703 Err(core.ErrNotFound). 704 Msg("element not found by selector") 705 706 return core.ErrNotFound 707 } 708 709 m.logger.Trace().Str("object_id", string(*found.ObjectID)).Msg("calculating clickable element points") 710 711 points, err := GetClickablePointByObjectID(ctx, m.client, *found.ObjectID) 712 713 if err != nil { 714 m.logger.Trace().Err(err).Msg("failed calculating clickable element points") 715 716 return err 717 } 718 719 m.logger.Trace().Float64("x", points.X).Float64("y", points.Y).Msg("calculated clickable element points") 720 721 m.logger.Trace().Msg("focusing on an element") 722 723 err = m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(*found.ObjectID)) 724 725 if err != nil { 726 m.logger.Trace().Err(err).Msg("failed to focus on an element") 727 728 return err 729 } 730 731 m.logger.Trace().Msg("clearing element") 732 733 if err := m.ClearByXY(ctx, points); err != nil { 734 m.logger.Trace().Err(err).Msg("failed to clear element") 735 736 return err 737 } 738 739 m.logger.Trace().Msg("cleared element") 740 741 return nil 742 } 743 744 func (m *Manager) ClearByXY(ctx context.Context, points Quad) error { 745 m.logger.Trace(). 746 Float64("x", points.X). 747 Float64("y", points.Y). 748 Msg("starting to clear element by coordinates") 749 750 delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond 751 752 m.logger.Trace().Dur("delay", delay).Msg("clicking mouse button to select text") 753 754 err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, 3) 755 756 if err != nil { 757 m.logger.Trace().Err(err).Msg("failed to click mouse button") 758 759 return err 760 } 761 762 delay = time.Duration(drivers.DefaultKeyboardDelay) * time.Millisecond 763 764 m.logger.Trace().Dur("delay", delay).Msg("pressing 'Backspace'") 765 766 if err := m.keyboard.Press(ctx, []string{"Backspace"}, 1, delay); err != nil { 767 m.logger.Trace().Err(err).Msg("failed to press 'Backspace'") 768 769 return err 770 } 771 772 return err 773 } 774 775 func (m *Manager) Press(ctx context.Context, keys []string, count int) error { 776 delay := time.Duration(drivers.DefaultKeyboardDelay) * time.Millisecond 777 778 m.logger.Trace(). 779 Strs("keys", keys). 780 Int("count", count). 781 Dur("delay", delay). 782 Msg("pressing keyboard keys") 783 784 if err := m.keyboard.Press(ctx, keys, count, delay); err != nil { 785 m.logger.Trace().Err(err).Msg("failed to press keyboard keys") 786 787 return err 788 } 789 790 return nil 791 } 792 793 func (m *Manager) PressBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector, keys []string, count int) error { 794 m.logger.Trace(). 795 Str("parent_object_id", string(id)). 796 Str("selector", selector.String()). 797 Strs("keys", keys). 798 Int("count", count). 799 Msg("starting to press keyboard keys by selector") 800 801 if err := m.FocusBySelector(ctx, id, selector); err != nil { 802 return err 803 } 804 805 return m.Press(ctx, keys, count) 806 } 807 808 func (m *Manager) Select(ctx context.Context, id runtime.RemoteObjectID, value *values.Array) (*values.Array, error) { 809 m.logger.Trace(). 810 Str("object_id", string(id)). 811 Msg("starting to select values") 812 813 if err := m.Focus(ctx, id); err != nil { 814 return values.NewArray(0), err 815 } 816 817 m.logger.Trace().Msg("selecting values") 818 m.logger.Trace().Msg("evaluating a JS function") 819 820 val, err := m.exec.EvalValue(ctx, templates.Select(id, value)) 821 822 if err != nil { 823 m.logger.Trace().Err(err).Msg("failed to evaluate a JS function") 824 825 return nil, err 826 } 827 828 m.logger.Trace().Msg("validating JS result") 829 830 arr, ok := val.(*values.Array) 831 832 if !ok { 833 m.logger.Trace().Err(err).Msg("JS result validation failed") 834 835 return values.NewArray(0), core.ErrUnexpected 836 } 837 838 m.logger.Trace().Msg("selected values") 839 840 return arr, nil 841 } 842 843 func (m *Manager) SelectBySelector(ctx context.Context, id runtime.RemoteObjectID, selector drivers.QuerySelector, value *values.Array) (*values.Array, error) { 844 m.logger.Trace(). 845 Str("parent_object_id", string(id)). 846 Str("selector", selector.String()). 847 Msg("starting to select values by selector") 848 849 if err := m.FocusBySelector(ctx, id, selector); err != nil { 850 return values.NewArray(0), err 851 } 852 853 m.logger.Trace().Msg("selecting values") 854 m.logger.Trace().Msg("evaluating a JS function") 855 856 res, err := m.exec.EvalValue(ctx, templates.SelectBySelector(id, selector, value)) 857 858 if err != nil { 859 m.logger.Trace().Err(err).Msg("failed to evaluate a JS function") 860 861 return values.NewArray(0), err 862 } 863 864 m.logger.Trace().Msg("validating JS result") 865 866 arr, ok := res.(*values.Array) 867 868 if !ok { 869 m.logger.Trace().Err(err).Msg("JS result validation failed") 870 871 return values.NewArray(0), core.ErrUnexpected 872 } 873 874 m.logger.Trace().Msg("selected values") 875 876 return arr, nil 877 }