| Line 416... |
Line 416... |
| 416 |
}
|
416 |
}
|
| 417 |
|
417 |
|
| 418 |
/** Seed probe, in slider px. Deliberately small: it only has to produce a first
|
418 |
/** Seed probe, in slider px. Deliberately small: it only has to produce a first
|
| 419 |
* measurable movement, and it must be too small to cross the hole. */
|
419 |
* measurable movement, and it must be too small to cross the hole. */
|
| 420 |
private static final int SEED_NUDGE = 12;
|
420 |
private static final int SEED_NUDGE = 12;
|
| - |
|
421 |
/** Sub-moves per leg, and the pause between them. A leg is traversed as many small
|
| - |
|
422 |
* eased steps rather than one jump, so the pointer describes a continuous path. */
|
| - |
|
423 |
private static final int MAX_GLIDE_STEPS = 18;
|
| - |
|
424 |
private static final int GLIDE_PX_PER_STEP = 8;
|
| - |
|
425 |
private static final long GLIDE_PAUSE_MS = 45;
|
| 421 |
private static final int MAX_AIM_STEPS = 5;
|
426 |
private static final int MAX_AIM_STEPS = 5;
|
| 422 |
private static final int MAX_STEP = 140;
|
427 |
private static final int MAX_STEP = 140;
|
| 423 |
|
428 |
|
| - |
|
429 |
/**
|
| - |
|
430 |
* Traverse one leg as many small eased sub-moves instead of a single jump.
|
| - |
|
431 |
*
|
| - |
|
432 |
* Nothing about the distance changes -- it is still whatever the derived ratio says.
|
| - |
|
433 |
* Only the path does. The widget scores trajectory as well as final position, and
|
| - |
|
434 |
* returns POSITION_MISMATCH for either, so a drag that teleports in 2 jumps and one
|
| - |
|
435 |
* that slides in over 15 are not equally credible. Realme holds ~1.93s and converts
|
| - |
|
436 |
* 54-74%; oppo held 0.91s in 2-3 jumps and converts 15%. That is suggestive, not
|
| - |
|
437 |
* proof -- this change is the test.
|
| - |
|
438 |
*
|
| - |
|
439 |
* Ease-out (1-(1-t)^2) so it starts quickly and settles, which is how a hand moves.
|
| - |
|
440 |
*/
|
| - |
|
441 |
private void glide(Actions actionProvider, int distance) throws InterruptedException {
|
| - |
|
442 |
int steps = Math.abs(distance) / GLIDE_PX_PER_STEP;
|
| - |
|
443 |
if (steps > MAX_GLIDE_STEPS) steps = MAX_GLIDE_STEPS;
|
| - |
|
444 |
if (steps <= 1) {
|
| - |
|
445 |
actionProvider.moveByOffset(distance, 0).perform();
|
| - |
|
446 |
return;
|
| - |
|
447 |
}
|
| - |
|
448 |
int done = 0;
|
| - |
|
449 |
for (int i = 1; i <= steps; i++) {
|
| - |
|
450 |
double t = (double) i / steps;
|
| - |
|
451 |
int cumulative = (int) Math.round(distance * (1 - Math.pow(1 - t, 2)));
|
| - |
|
452 |
int delta = cumulative - done;
|
| - |
|
453 |
if (delta != 0) {
|
| - |
|
454 |
actionProvider.moveByOffset(delta, 0).perform();
|
| - |
|
455 |
done += delta;
|
| - |
|
456 |
}
|
| - |
|
457 |
Thread.sleep(GLIDE_PAUSE_MS);
|
| - |
|
458 |
}
|
| - |
|
459 |
if (done != distance) {
|
| - |
|
460 |
actionProvider.moveByOffset(distance - done, 0).perform();
|
| - |
|
461 |
}
|
| - |
|
462 |
}
|
| - |
|
463 |
|
| 424 |
/** Centre of the draggable ring, in page CSS px, or null if it is not there. */
|
464 |
/** Centre of the draggable ring, in page CSS px, or null if it is not there. */
|
| 425 |
private Double pieceCentreX(WebDriver driver) {
|
465 |
private Double pieceCentreX(WebDriver driver) {
|
| 426 |
try {
|
466 |
try {
|
| 427 |
WebElement piece = driver.findElement(By.xpath("//*[starts-with(@id, 'dx_captcha_basic_sub-slider_')]"));
|
467 |
WebElement piece = driver.findElement(By.xpath("//*[starts-with(@id, 'dx_captcha_basic_sub-slider_')]"));
|
| 428 |
return piece.getLocation().getX() + (piece.getSize().getWidth() / 2.0);
|
468 |
return piece.getLocation().getX() + (piece.getSize().getWidth() / 2.0);
|
| Line 481... |
Line 521... |
| 481 |
double ratio = 0; // ring px per mouse px, signed, derived from real moves
|
521 |
double ratio = 0; // ring px per mouse px, signed, derived from real moves
|
| 482 |
int total = 0;
|
522 |
int total = 0;
|
| 483 |
int step = SEED_NUDGE;
|
523 |
int step = SEED_NUDGE;
|
| 484 |
|
524 |
|
| 485 |
for (int i = 0; i < MAX_AIM_STEPS; i++) {
|
525 |
for (int i = 0; i < MAX_AIM_STEPS; i++) {
|
| 486 |
actionProvider.moveByOffset(step, 0).perform();
|
526 |
glide(actionProvider, step);
|
| 487 |
total += step;
|
527 |
total += step;
|
| 488 |
|
528 |
|
| 489 |
Double now = pieceCentreX(driver);
|
529 |
Double now = pieceCentreX(driver);
|
| 490 |
if (now == null) {
|
530 |
if (now == null) {
|
| 491 |
LOGGER.warn("Aim step {}: lost the ring after {}px", i, total);
|
531 |
LOGGER.warn("Aim step {}: lost the ring after {}px", i, total);
|