Skip to content

Commit

Permalink
Issue CollaboraOnline#28: Retry on StaleElementReference exception.
Browse files Browse the repository at this point in the history
  • Loading branch information
donquixote committed Nov 5, 2024
1 parent a5aa020 commit 75c718b
Showing 1 changed file with 43 additions and 12 deletions.
55 changes: 43 additions & 12 deletions tests/src/ExistingSiteJavascript/CollaboraIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Drupal\file\Entity\File;
use Drupal\media\Entity\Media;
use Drupal\media\MediaInterface;
use WebDriver\Exception\StaleElementReference;
use weitzman\DrupalTestTraits\ExistingSiteSelenium2DriverTestBase;

/**
Expand Down Expand Up @@ -62,18 +63,22 @@ public function testCollaboraPreview(): void {
// The document text is in a canvas element, so instead we compare the
// word count and character count.
// Wait until the word counter element appears and has a value.
$this->waitUntilNoMessage(function (): string|null {
$element = $this->getCurrentPage()->find('css', 'div#StateWordCount');
if (!$element) {
return 'Word count element not found.';
}
$count_string = $element->getText();
if (!$count_string) {
return 'Word count string is empty.';
}
$this->assertSame('2 words, 18 characters', $count_string);
return NULL;
});
$this->waitUntilNoMessage(
fn (): string|null => $this->retryIfStaleElement(
function (): string|null {
$element = $this->getCurrentPage()->find('css', 'div#StateWordCount');
if (!$element) {
return 'Word count element not found.';
}
$count_string = $element->getText();
if (!$count_string) {
return 'Word count string is empty.';
}
$this->assertSame('2 words, 18 characters', $count_string);
return NULL;
},
),
);
}

/**
Expand Down Expand Up @@ -112,6 +117,32 @@ protected function createDocumentMedia(string $media_name, string $file_basename
return $media;
}

/**
* Calls a callback until it does not throw a StaleElementReference.
*
* @template T
*
* @param callable(): T $callback
* Callback to call and retry.
* @param int $max_calls
* Maximum number of times the callback should be called.
*
* @return T
* Return value from the last call to the callback.
*/
protected function retryIfStaleElement(callable $callback, int $max_calls = 10): mixed {
for ($i = 1; $i < $max_calls; ++$i) {
try {
return $callback();
}
catch (StaleElementReference) {
// Next iteration.
}
}
// Call it one more time, without try/catch.
return $callback();
}

/**
* Waits until a callback returns NULL.
*
Expand Down

0 comments on commit 75c718b

Please sign in to comment.