• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1async function waitForScrollendEvent(test, target, timeoutMs = 500) {
2  return new Promise((resolve, reject) => {
3    const timeoutCallback = test.step_timeout(() => {
4      reject(`No Scrollend event received for target ${target}`);
5    }, timeoutMs);
6    target.addEventListener('scrollend', (evt) => {
7      clearTimeout(timeoutCallback);
8      resolve(evt);
9    }, { once: true });
10  });
11}
12
13const MAX_FRAME = 700;
14const MAX_UNCHANGED_FRAMES = 20;
15
16// Returns a promise that resolves when the given condition is met or rejects
17// after MAX_FRAME animation frames.
18// TODO(crbug.com/1400399): deprecate. We should not use frame based waits in
19// WPT as frame rates may vary greatly in different testing environments.
20function waitFor(condition, error_message = 'Reaches the maximum frames.') {
21  return new Promise((resolve, reject) => {
22    function tick(frames) {
23      // We requestAnimationFrame either for MAX_FRAM frames or until condition
24      // is met.
25      if (frames >= MAX_FRAME)
26        reject(error_message);
27      else if (condition())
28        resolve();
29      else
30        requestAnimationFrame(tick.bind(this, frames + 1));
31    }
32    tick(0);
33  });
34}
35
36// TODO(crbug.com/1400446): Test driver should defer sending events until the
37// browser is ready. Also the term compositor-commit is misleading as not all
38// user-agents use a compositor process.
39function waitForCompositorCommit() {
40  return new Promise((resolve) => {
41    // rAF twice.
42    window.requestAnimationFrame(() => {
43      window.requestAnimationFrame(resolve);
44    });
45  });
46}
47
48// TODO(crbug.com/1400399): Deprecate as frame rates may vary greatly in
49// different test environments.
50function waitForAnimationEnd(getValue) {
51  var last_changed_frame = 0;
52  var last_position = getValue();
53  return new Promise((resolve, reject) => {
54    function tick(frames) {
55    // We requestAnimationFrame either for MAX_FRAME or until
56    // MAX_UNCHANGED_FRAMES with no change have been observed.
57      if (frames >= MAX_FRAME || frames - last_changed_frame > MAX_UNCHANGED_FRAMES) {
58        resolve();
59      } else {
60        current_value = getValue();
61        if (last_position != current_value) {
62          last_changed_frame = frames;
63          last_position = current_value;
64        }
65        requestAnimationFrame(tick.bind(this, frames + 1));
66      }
67    }
68    tick(0);
69  })
70}
71
72// Scrolls in target according to move_path with pauses in between
73function touchScrollInTargetSequentiallyWithPause(target, move_path, pause_time_in_ms = 100) {
74  const test_driver_actions = new test_driver.Actions()
75    .addPointer("pointer1", "touch")
76    .pointerMove(0, 0, {origin: target})
77    .pointerDown();
78
79  const substeps = 5;
80  let x = 0;
81  let y = 0;
82  // Do each move in 5 steps
83  for(let move of move_path) {
84    let step_x = (move.x - x) / substeps;
85    let step_y = (move.y - y) / substeps;
86    for(let step = 0; step < substeps; step++) {
87      x += step_x;
88      y += step_y;
89      test_driver_actions.pointerMove(x, y, {origin: target});
90    }
91    test_driver_actions.pause(pause_time_in_ms);
92  }
93
94  return test_driver_actions.pointerUp().send();
95}
96
97function touchScrollInTarget(pixels_to_scroll, target, direction, pause_time_in_ms = 100) {
98  var x_delta = 0;
99  var y_delta = 0;
100  const num_movs = 5;
101  if (direction == "down") {
102    y_delta = -1 * pixels_to_scroll / num_movs;
103  } else if (direction == "up") {
104    y_delta = pixels_to_scroll / num_movs;
105  } else if (direction == "right") {
106    x_delta = -1 * pixels_to_scroll / num_movs;
107  } else if (direction == "left") {
108    x_delta = pixels_to_scroll / num_movs;
109  } else {
110    throw("scroll direction '" + direction + "' is not expected, direction should be 'down', 'up', 'left' or 'right'");
111  }
112  return new test_driver.Actions()
113      .addPointer("pointer1", "touch")
114      .pointerMove(0, 0, {origin: target})
115      .pointerDown()
116      .pointerMove(x_delta, y_delta, {origin: target})
117      .pointerMove(2 * x_delta, 2 * y_delta, {origin: target})
118      .pointerMove(3 * x_delta, 3 * y_delta, {origin: target})
119      .pointerMove(4 * x_delta, 4 * y_delta, {origin: target})
120      .pointerMove(5 * x_delta, 5 * y_delta, {origin: target})
121      .pause(pause_time_in_ms)
122      .pointerUp()
123      .send();
124}
125
126// Trigger fling by doing pointerUp right after pointerMoves.
127function touchFlingInTarget(pixels_to_scroll, target, direction) {
128  touchScrollInTarget(pixels_to_scroll, target, direction, 0 /* pause_time */);
129}
130
131function mouseActionsInTarget(target, origin, delta, pause_time_in_ms = 100) {
132  return new test_driver.Actions()
133    .addPointer("pointer1", "mouse")
134    .pointerMove(origin.x, origin.y, { origin: target })
135    .pointerDown()
136    .pointerMove(origin.x + delta.x, origin.y + delta.y, { origin: target })
137    .pointerMove(origin.x + delta.x * 2, origin.y + delta.y * 2, { origin: target })
138    .pause(pause_time_in_ms)
139    .pointerUp()
140    .send();
141}
142
143// Returns a promise that resolves when the given condition holds for 10
144// animation frames or rejects if the condition changes to false within 10
145// animation frames.
146// TODO(crbug.com/1400399): Deprecate as frame rates may very greatly in
147// different test environments.
148function conditionHolds(condition, error_message = 'Condition is not true anymore.') {
149  const MAX_FRAME = 10;
150  return new Promise((resolve, reject) => {
151    function tick(frames) {
152      // We requestAnimationFrame either for 10 frames or until condition is
153      // violated.
154      if (frames >= MAX_FRAME)
155        resolve();
156      else if (!condition())
157        reject(error_message);
158      else
159        requestAnimationFrame(tick.bind(this, frames + 1));
160    }
161    tick(0);
162  });
163}
164