Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const { I } = inject();
 
const Helpers = require("../tests/helpers");
 
/**
 * @typedef BoundingClientRect
 * @property {number} x
 * @property {number} y
 * @property {number} width
 * @property {number} height
 */
 
module.exports = {
  _rootSelector: ".lsf-video-segmentation",
  _videoRootSelector: ".lsf-video__main",
  _trackSelector: ".lsf-seeker__track",
  _indicatorSelector: ".lsf-seeker__indicator",
  _positionSelector: ".lsf-seeker__position",
  _seekStepForwardSelector: 'button[aria-label="Step forward"]',
  _seekStepBackwardSelector: 'button[aria-label="Step backward"]',
  _playButtonSelector: 'button[aria-label="Play"]',
 
  locateRootSelector() {
    return locate(this._rootSelector);
  },
 
  locateVideoContainer() {
    return locate(this._videoRootSelector);
  },
 
  videoLocate(locator) {
    return locator ? locate(locator).inside(this.locateVideoContainer()) : this.locateVideoContainer();
  },
 
  seekStepForwardSelector() {
    return locate(this._seekStepForwardSelector).inside(this.locateRootSelector());
  },
 
  seekStepBackwardSelector() {
    return locate(this._seekStepBackwardSelector).inside(this.locateRootSelector());
  },
 
  playButtonSelector() {
    return locate(this._playButtonSelector).inside(this.locateRootSelector());
  },
 
  getCurrentVideo() {
    return I.executeScript(Helpers.getCurrentMedia, "video");
  },
 
  /**
   * Grab the bounding rect of the video track
   * @returns {Promise<BoundingClientRect>}
   */
  async grabTrackBoundingRect() {
    return I.grabElementBoundingRect(this._trackSelector);
  },
 
  /**
   * Grab the bounding rect of the video indicator (the slider that outlines the viewable region)
   * @returns {Promise<BoundingClientRect>}
   */
  async grabIndicatorBoundingRect() {
    return I.grabElementBoundingRect(this._indicatorSelector);
  },
 
  /**
   * Grab the bounding rect of the video position (the playhead/cursor element).
   * @returns {Promise<BoundingClientRect>}
   */
  async grabPositionBoundingRect() {
    return I.grabElementBoundingRect(this._positionSelector);
  },
 
  /**
   * Drag the element to the given position
   * @param {BoundingClientRect} bbox
   * @param {number} x
   * @param {number} [y=undefined]
   * @returns {Promise<void>}
   */
  async drag(bbox, x, y) {
    const from = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };
    const to = { x, y: y || from.y };
 
    return I.dragAndDropMouse(from, to);
  },
 
  /**
   * Seek forward steps
   * @param {number} steps
   * @returns {Promise<void>}
   */
  async clickSeekStepForward(steps = 1) {
    for (let i = 0; i < steps; i++) {
      I.click(this.seekStepForwardSelector());
    }
  },
 
  /**
   * Seek backward steps
   * @param {number} steps
   * @returns {Promise<void>}
   */
  async clickSeekStepBackward(steps = 2) {
    for (let i = 0; i < steps; i++) {
      I.click(this.seekStepBackwardSelector());
    }
  },
 
  /**
   * Click the video controls play button.
   * @returns {Promise<void>}
   */
  async clickPlayButton() {
    I.click(this.playButtonSelector());
  },
 
  /**
   * Click the video controls pause button.
   * @returns {Promise<void>}
   */
  async clickPauseButton() {
    I.click(this.playButtonSelector());
  },
};