Skip to content

Commit 82cf388

Browse files
Fixed timeout error message that contain percent characters when calling waitForTextIn (#1029)
* Added test that shows problem with waitForTextIn timeout error message * Added fix for waitForTextIn timeout error messages containing a percent character * Removed code duplication * Added tests for other methods * Update WaitsForElements.php --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent bf6d693 commit 82cf388

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/Concerns/WaitsForElements.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public function waitForText($text, $seconds = null)
123123
*/
124124
public function waitForTextIn($selector, $text, $seconds = null)
125125
{
126-
$message = 'Waited %s seconds for text "'.$text.'" in selector '.$selector;
126+
$message = 'Waited %s seconds for text "'.$this->escapePercentCharacters($text).'" in selector '.$selector;
127127

128128
return $this->waitUsing($seconds, 100, function () use ($selector, $text) {
129129
return $this->assertSeeIn($selector, $text);
@@ -427,6 +427,17 @@ public function waitUsing($seconds, $interval, Closure $callback, $message = nul
427427
*/
428428
protected function formatTimeOutMessage($message, $expected)
429429
{
430-
return $message.' ['.str_replace('%', '%%', $expected).'].';
430+
return $message.' ['.$this->escapePercentCharacters($expected).'].';
431+
}
432+
433+
/**
434+
* Escape percent characters in preparation for sending the given message to "sprintf".
435+
*
436+
* @param string $message
437+
* @return string
438+
*/
439+
protected function escapePercentCharacters($message)
440+
{
441+
return str_replace('%', '%%', $message);
431442
}
432443
}

tests/WaitsForElementsTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,24 @@ public function test_wait_until_missing()
195195
$browser->waitUntilMissing('foo');
196196
}
197197

198+
public function test_wait_until_missing_text_failure_message_containing_a_percent_character()
199+
{
200+
$element = m::mock(stdClass::class);
201+
$element->shouldReceive('getText')->andReturn('Discount: 20%');
202+
203+
$resolver = m::mock(stdClass::class);
204+
$resolver->shouldReceive('findOrFail')->with('')->andReturn($element);
205+
206+
$browser = new Browser(new stdClass, $resolver);
207+
208+
try {
209+
$browser->waitUntilMissingText('Discount: 20%', 1);
210+
$this->fail('waitUntilMissingText() did not timeout.');
211+
} catch (TimeOutException $e) {
212+
$this->assertSame('Waited 1 seconds for removal of text [Discount: 20%].', $e->getMessage());
213+
}
214+
}
215+
198216
public function test_wait_for_text_failure_message_containing_a_percent_character()
199217
{
200218
$element = m::mock(stdClass::class);
@@ -213,6 +231,57 @@ public function test_wait_for_text_failure_message_containing_a_percent_characte
213231
}
214232
}
215233

234+
public function test_wait_for_text_in_failure_message_containing_a_percent_character()
235+
{
236+
$element = m::mock(stdClass::class);
237+
$element->shouldReceive('getText')->andReturn('Discount: None');
238+
239+
$resolver = m::mock(stdClass::class);
240+
$resolver->shouldReceive('format')->with('foo')->andReturn('body foo');
241+
$resolver->shouldReceive('findOrFail')->with('foo')->andReturn($element);
242+
243+
$browser = new Browser(new stdClass, $resolver);
244+
245+
try {
246+
$browser->waitForTextIn('foo', 'Discount: 20%', 1);
247+
$this->fail('waitForTextIn() did not timeout.');
248+
} catch (TimeOutException $e) {
249+
$this->assertSame('Waited 1 seconds for text "Discount: 20%" in selector foo', $e->getMessage());
250+
}
251+
}
252+
253+
public function test_wait_for_link_failure_message_containing_a_percent_character()
254+
{
255+
$driver = m::mock(stdClass::class);
256+
$driver->shouldReceive('executeScript')
257+
->andReturnFalse();
258+
259+
$browser = new Browser($driver);
260+
261+
try {
262+
$browser->waitForLink('https://laravel.com?q=foo%20bar', 1);
263+
$this->fail('waitForLink() did not timeout.');
264+
} catch (TimeOutException $e) {
265+
$this->assertSame('Waited 1 seconds for link [https://laravel.com?q=foo%20bar].', $e->getMessage());
266+
}
267+
}
268+
269+
public function test_wait_for_location_failure_message_containing_a_percent_character()
270+
{
271+
$driver = m::mock(stdClass::class);
272+
$driver->shouldReceive('executeScript')
273+
->andReturnFalse();
274+
275+
$browser = new Browser($driver);
276+
277+
try {
278+
$browser->waitForLocation('https://laravel.com?q=foo%20bar', 1);
279+
$this->fail('waitForLocation() did not timeout.');
280+
} catch (TimeOutException $e) {
281+
$this->assertSame('Waited 1 seconds for location [https://laravel.com?q=foo%20bar].', $e->getMessage());
282+
}
283+
}
284+
216285
public function test_wait_for_an_element_to_be_enabled()
217286
{
218287
$element = m::mock(stdClass::class);

0 commit comments

Comments
 (0)