Refactor for E2E

This commit is contained in:
An Phan 2016-11-24 11:56:00 +08:00
parent 46266409d5
commit 46a52a55a6
No known key found for this signature in database
GPG key ID: 05536BB4BCDC02A2
10 changed files with 261 additions and 144 deletions

View file

@ -10,9 +10,8 @@ class PlaylistScreenTest extends TestCase
{ {
$this->loginAndGoTo('songs') $this->loginAndGoTo('songs')
->selectRange() ->selectRange()
->createPlaylist('Bar'); ->createPlaylist('Bar')
->seeText('Bar', '#playlists > ul');
$this->seeText('Bar', '#playlists > ul');
$this->click('#sidebar .playlist:nth-last-child(1)'); $this->click('#sidebar .playlist:nth-last-child(1)');
$this->see('#playlistWrapper'); $this->see('#playlistWrapper');

View file

@ -9,17 +9,17 @@ class ProfileScreenTest extends TestCase
{ {
public function testProfileScreen() public function testProfileScreen()
{ {
$this->loginAndWait(); $this->loginAndWait()
$this->click('a.view-profile'); ->click('a.view-profile');
$this->see('#profileWrapper'); $this->see('#profileWrapper')
// Now we change some user profile details // Now we change some user profile details
$this->typeIn('#profileWrapper input[name="name"]', 'Mr Bar'); ->typeIn('#profileWrapper input[name="name"]', 'Mr Bar')
$this->typeIn('#profileWrapper input[name="email"]', 'bar@koel.net'); ->typeIn('#profileWrapper input[name="email"]', 'bar@koel.net')
$this->enter(); ->enter()
$this->see('.sweet-alert'); ->see('.sweet-alert')
// Dismiss the alert first // Dismiss the alert first
$this->press(WebDriverKeys::ESCAPE); ->press(WebDriverKeys::ESCAPE)
$this->notSee('.sweet-alert'); ->notSee('.sweet-alert');
$avatar = $this->el('a.view-profile img'); $avatar = $this->el('a.view-profile img');
// Expect the Gravatar to be updated // Expect the Gravatar to be updated
@ -27,17 +27,17 @@ class ProfileScreenTest extends TestCase
// Check "Confirm Closing" and validate its functionality // Check "Confirm Closing" and validate its functionality
$this->click('#profileWrapper input[name="confirmClosing"]'); $this->click('#profileWrapper input[name="confirmClosing"]');
$this->refresh(); $this->refresh()
$this->waitUntil(WebDriverExpectedCondition::alertIsPresent()); ->waitUntil(WebDriverExpectedCondition::alertIsPresent());
$this->driver->switchTo()->alert()->dismiss(); $this->driver->switchTo()->alert()->dismiss();
// Reverse all changes for other tests to not be affected // Reverse all changes for other tests to not be affected
$this->typeIn('#profileWrapper input[name="name"]', 'Koel Admin'); $this->typeIn('#profileWrapper input[name="name"]', 'Koel Admin')
$this->typeIn('#profileWrapper input[name="email"]', 'koel@example.com'); ->typeIn('#profileWrapper input[name="email"]', 'koel@example.com')
$this->enter(); ->enter()
$this->see('.sweet-alert'); ->see('.sweet-alert')
$this->press(WebDriverKeys::ESCAPE); ->press(WebDriverKeys::ESCAPE)
$this->notSee('.sweet-alert'); ->notSee('.sweet-alert')
$this->click('#profileWrapper input[name="confirmClosing"]'); ->click('#profileWrapper input[name="confirmClosing"]');
} }
} }

View file

@ -11,9 +11,7 @@ class QueueScreenTest extends TestCase
// As the queue is currently empty, the "Shuffling all song" link should be there // As the queue is currently empty, the "Shuffling all song" link should be there
$this->click('#queueWrapper a.start'); $this->click('#queueWrapper a.start');
$this->waitUntil(function () { $this->see('#queueWrapper .song-item');
return count($this->els('#queueWrapper .song-item'));
});
// Clear the queue // Clear the queue
$this->click('#queueWrapper .buttons button.btn-clear-queue'); $this->click('#queueWrapper .buttons button.btn-clear-queue');

View file

@ -10,34 +10,32 @@ class SideBarTest extends TestCase
// All basic navigation // All basic navigation
foreach (['home', 'queue', 'songs', 'albums', 'artists', 'youtube', 'settings', 'users'] as $screen) { foreach (['home', 'queue', 'songs', 'albums', 'artists', 'youtube', 'settings', 'users'] as $screen) {
$this->goto($screen); $this->goto($screen)
$this->waitUntil(function () use ($screen) { ->waitUntil(function () use ($screen) {
return $this->driver->getCurrentURL() === $this->url.'/#!/'.$screen; return $this->driver->getCurrentURL() === $this->url.'/#!/'.$screen;
}); });
} }
// Add a playlist // Add a playlist
$this->click('#playlists > h1 > i.create'); $this->click('#playlists > h1 > i.create');
$this->see('#playlists > form.create'); $this->see('#playlists > form.create')
$this->typeIn('#playlists > form > input[type="text"]', 'Bar'); ->typeIn('#playlists > form > input[type="text"]', 'Bar')
$this->enter(); ->enter()
$this->waitUntil(function () { ->waitUntil(function () {
$list = $this->els('#playlists .playlist'); $list = $this->els('#playlists .playlist');
return end($list)->getText() === 'Bar';
return end($list)->getText() === 'Bar'; });
});
// Double click to edit/rename a playlist // Double click to edit/rename a playlist
$this->doubleClick('#playlists .playlist:nth-child(2)'); $this->doubleClick('#playlists .playlist:nth-child(2)')
$this->see('#playlists .playlist:nth-child(2) input[type="text"]'); ->see('#playlists .playlist:nth-child(2) input[type="text"]')
$this->typeIn('#playlists .playlist:nth-child(2) input[type="text"]', 'Qux'); ->typeIn('#playlists .playlist:nth-child(2) input[type="text"]', 'Qux')
$this->enter(); ->enter()
$this->seeText('Qux', '#playlists .playlist:nth-child(2)'); ->seeText('Qux', '#playlists .playlist:nth-child(2)');
// Edit with an empty name shouldn't do anything. // Edit with an empty name shouldn't do anything.
$this->doubleClick('#playlists .playlist:nth-child(2)'); $this->doubleClick('#playlists .playlist:nth-child(2)');
$this->click('#playlists .playlist:nth-child(2) input[type="text"]')->clear(); $this->click('#playlists .playlist:nth-child(2) input[type="text"]')->clear();
$this->enter(); $this->enter()->seeText('Qux', '#playlists .playlist:nth-child(2)');
$this->seeText('Qux', '#playlists .playlist:nth-child(2)');
} }
} }

View file

@ -55,13 +55,11 @@ trait SongListActions
*/ */
public function cmdSelectSongs() public function cmdSelectSongs()
{ {
$actions = (new WebDriverActions($this->driver)) $actions = (new WebDriverActions($this->driver))->keyDown(null, WebDriverKeys::COMMAND);
->keyDown(null, WebDriverKeys::COMMAND);
foreach (func_get_args() as $i) { foreach (func_get_args() as $i) {
$actions->click($this->el("{$this->wrapperId} tr.song-item:nth-child($i)")); $actions->click($this->el("{$this->wrapperId} tr.song-item:nth-child($i)"));
} }
$actions->keyUp(null, WebDriverKeys::COMMAND) $actions->keyUp(null, WebDriverKeys::COMMAND)->perform();
->perform();
return $this; return $this;
} }
@ -77,8 +75,8 @@ trait SongListActions
{ {
// Try adding a song into a new playlist // Try adding a song into a new playlist
$this->click("{$this->wrapperId} .buttons button.btn-add-to"); $this->click("{$this->wrapperId} .buttons button.btn-add-to");
$this->typeIn("{$this->wrapperId} .buttons input[type='text']", $playlistName); $this->typeIn("{$this->wrapperId} .buttons input[type='text']", $playlistName)
$this->enter(); ->enter();
return $this; return $this;
} }

View file

@ -4,7 +4,6 @@ namespace E2E;
use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverElement; use Facebook\WebDriver\WebDriverElement;
use Facebook\WebDriver\WebDriverExpectedCondition;
use Facebook\WebDriver\WebDriverKeys; use Facebook\WebDriver\WebDriverKeys;
class SongListTest extends TestCase class SongListTest extends TestCase
@ -38,8 +37,7 @@ class SongListTest extends TestCase
); );
// Delete key should remove selected songs // Delete key should remove selected songs
$this->press(WebDriverKeys::DELETE); $this->press(WebDriverKeys::DELETE)->waitUntil(function () {
$this->waitUntil(function () {
return count($this->els('#queueWrapper tr.song-item.selected')) === 0 return count($this->els('#queueWrapper tr.song-item.selected')) === 0
&& count($this->els('#queueWrapper tr.song-item')) === 7; && count($this->els('#queueWrapper tr.song-item')) === 7;
}); });
@ -51,18 +49,13 @@ class SongListTest extends TestCase
public function testActionButtons() public function testActionButtons()
{ {
$this->loginAndWait()->repopulateList(); $this->loginAndWait()
->repopulateList()
// Since no songs are selected, the "Shuffle All" button must be shown // Since no songs are selected, the "Shuffle All" button must be shown
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated( ->see('#queueWrapper button.btn-shuffle-all')
WebDriverBy::cssSelector('#queueWrapper button.btn-shuffle-all') // Now we selected all songs for the "Shuffle Selected" button to be shown
)); ->selectAllSongs()
->see('#queueWrapper button.btn-shuffle-selected');
// Now we selected all songs for the "Shuffle Selected" button to be shown
$this->selectAllSongs();
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated(
WebDriverBy::cssSelector('#queueWrapper button.btn-shuffle-selected')
));
// Add to favorites // Add to favorites
$this->selectSong(); $this->selectSong();
@ -71,13 +64,11 @@ class SongListTest extends TestCase
$this->goto('favorites'); $this->goto('favorites');
static::assertCount(1, $this->els('#favoritesWrapper tr.song-item')); static::assertCount(1, $this->els('#favoritesWrapper tr.song-item'));
$this->goto('queue'); $this->goto('queue')
$this->selectSong(); ->selectSong();
// Try adding a song into a new playlist // Try adding a song into a new playlist
$this->createPlaylist('Foo'); $this->createPlaylist('Foo')
$this->waitUntil(WebDriverExpectedCondition::textToBePresentInElement( ->seeText('Foo', '#playlists > ul');
WebDriverBy::cssSelector('#playlists > ul'), 'Foo'
));
} }
public function testSorting() public function testSorting()
@ -97,8 +88,8 @@ class SongListTest extends TestCase
} }
// Now go to All Songs screen and sort there // Now go to All Songs screen and sort there
$this->goto('songs'); $this->goto('songs')
$this->click('#songsWrapper div.song-list-wrap th:nth-child(2)'); ->click('#songsWrapper div.song-list-wrap th:nth-child(2)');
$last = null; $last = null;
$results = []; $results = [];
/** @var WebDriverElement $td */ /** @var WebDriverElement $td */
@ -124,43 +115,34 @@ class SongListTest extends TestCase
public function testContextMenu() public function testContextMenu()
{ {
$this->loginAndGoTo('songs'); $this->loginAndGoTo('songs')
$this->rightClickOnSong(); ->rightClickOnSong()
->see('#songsWrapper .song-menu');
$by = WebDriverBy::cssSelector('#songsWrapper .song-menu');
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated($by));
// 7 sub menu items // 7 sub menu items
static::assertCount(7, $this->els('#songsWrapper .song-menu > li')); static::assertCount(7, $this->els('#songsWrapper .song-menu > li'));
// Clicking the "Go to Album" menu item // Clicking the "Go to Album" menu item
$this->click('#songsWrapper .song-menu > li:nth-child(2)'); $this->click('#songsWrapper .song-menu > li:nth-child(2)');
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated( $this->see('#albumWrapper');
WebDriverBy::cssSelector('#albumWrapper')
));
// Clicking the "Go to Artist" menu item // Clicking the "Go to Artist" menu item
$this->back(); $this->back()
$this->rightClickOnSong(); ->rightClickOnSong()
$this->click('#songsWrapper .song-menu > li:nth-child(3)'); ->click('#songsWrapper .song-menu > li:nth-child(3)');
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated( $this->see('#artistWrapper');
WebDriverBy::cssSelector('#artistWrapper')
));
// Clicking "Edit" // Clicking "Edit"
$this->back(); $this->back()
$this->rightClickOnSong(); ->rightClickOnSong()
$this->click('#songsWrapper .song-menu > li:nth-child(5)'); ->click('#songsWrapper .song-menu > li:nth-child(5)');
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated( $this->see('#editSongsOverlay form');
WebDriverBy::cssSelector('#editSongsOverlay form')
));
// Updating song // Updating song
$this->typeIn('#editSongsOverlay form input[name="title"]', 'Foo'); $this->typeIn('#editSongsOverlay form input[name="title"]', 'Foo')
$this->typeIn('#editSongsOverlay form input[name="track"]', 99); ->typeIn('#editSongsOverlay form input[name="track"]', 99)
$this->enter(); ->enter()
$this->waitUntil(WebDriverExpectedCondition::invisibilityOfElementLocated( ->notSee('#editSongsOverlay form');
WebDriverBy::cssSelector('#editSongsOverlay form')
));
static::assertEquals('99', $this->el('#songsWrapper tr.song-item:nth-child(1) .track-number')->getText()); static::assertEquals('99', $this->el('#songsWrapper tr.song-item:nth-child(1) .track-number')->getText());
static::assertEquals('Foo', $this->el('#songsWrapper tr.song-item:nth-child(1) .title')->getText()); static::assertEquals('Foo', $this->el('#songsWrapper tr.song-item:nth-child(1) .title')->getText());
} }
@ -171,5 +153,7 @@ class SongListTest extends TestCase
$this->goto('albums'); $this->goto('albums');
$this->click('#albumsWrapper > div > article:nth-child(1) .meta a.shuffle-album'); $this->click('#albumsWrapper > div > article:nth-child(1) .meta a.shuffle-album');
$this->goto('queue'); $this->goto('queue');
return $this;
} }
} }

View file

@ -58,6 +58,9 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
return $this->app; return $this->app;
} }
/**
* Reset the test data for E2E tests.
*/
protected function resetData() protected function resetData()
{ {
// Make sure we have a fresh database. // Make sure we have a fresh database.
@ -90,16 +93,23 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
return $this; return $this;
} }
/**
* Log in and wait for the app to finish loading.
*
* @return $this
*
* @throws \Exception
*/
protected function loginAndWait() protected function loginAndWait()
{ {
$this->login(); $this->login()
$this->seeText('Koel Admin', '#userBadge > a.view-profile'); ->seeText('Koel Admin', '#userBadge > a.view-profile');
return $this; return $this;
} }
/** /**
* A helper to allow going to a specific screen. * Go to a specific screen.
* *
* @param $screen * @param $screen
* *
@ -122,11 +132,23 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase
return $this; return $this;
} }
/**
* Log in and go to a specific screen.
*
* @param $screen string
*
* @return $this
*
* @throws \Exception
*/
protected function loginAndGoTo($screen) protected function loginAndGoTo($screen)
{ {
return $this->loginAndWait()->goto($screen); return $this->loginAndWait()->goto($screen);
} }
/**
* Wait for the user to press ENTER key before continuing.
*/
protected function waitForUserInput() protected function waitForUserInput()
{ {
if (trim(fgets(fopen('php://stdin', 'rb'))) !== chr(13)) { if (trim(fgets(fopen('php://stdin', 'rb'))) !== chr(13)) {

View file

@ -8,26 +8,25 @@ class UsersScreenTest extends TestCase
{ {
public function testUsersScreen() public function testUsersScreen()
{ {
$this->loginAndGoTo('users'); $this->loginAndGoTo('users')->see('.user-item.me');
$this->see('.user-item.me');
// Hover to the first user item // Hover to the first user item
(new WebDriverMouseMoveAction($this->driver->getMouse(), $this->el('#usersWrapper .user-item.me'))) (new WebDriverMouseMoveAction($this->driver->getMouse(), $this->el('#usersWrapper .user-item.me')))
->perform(); ->perform();
// and validate that the button reads "Update Profile" instead of "Edit" // and validate that the button reads "Update Profile" instead of "Edit"
static::assertContains('Update Profile', $this->el('#usersWrapper .user-item.me .btn-edit')->getText()); static::assertContains('Update Profile',
$this->el('#usersWrapper .user-item.me .btn-edit')->getText());
// Also, clicking it should show the "Profile & Preferences" panel // Also, clicking it should show the "Profile & Preferences" panel
$this->click('#usersWrapper .user-item.me .btn-edit'); $this->click('#usersWrapper .user-item.me .btn-edit');
$this->see('#profileWrapper'); $this->see('#profileWrapper')
$this->back(); ->back()
// Add new user
// Add new user ->click('#usersWrapper .btn-add');
$this->click('#usersWrapper .btn-add'); $this->see('form.user-create')
$this->see('form.user-create'); ->typeIn('form.user-create input[name="name"]', 'Foo')
$this->typeIn('form.user-create input[name="name"]', 'Foo'); ->typeIn('form.user-create input[name="email"]', 'foo@koel.net')
$this->typeIn('form.user-create input[name="email"]', 'foo@koel.net'); ->typeIn('form.user-create input[name="password"]', 'SecureMuch')
$this->typeIn('form.user-create input[name="password"]', 'SecureMuch'); ->enter()
$this->enter(); ->seeText('foo@koel.net', '#usersWrapper');
$this->seeText('foo@koel.net', '#usersWrapper');
// Hover the next user item (not me) // Hover the next user item (not me)
(new WebDriverMouseMoveAction($this->driver->getMouse(), $this->el('#usersWrapper .user-item:not(.me)'))) (new WebDriverMouseMoveAction($this->driver->getMouse(), $this->el('#usersWrapper .user-item:not(.me)')))
@ -35,9 +34,9 @@ class UsersScreenTest extends TestCase
static::assertContains('Edit', $this->el('#usersWrapper .user-item:not(.me) .btn-edit')->getText()); static::assertContains('Edit', $this->el('#usersWrapper .user-item:not(.me) .btn-edit')->getText());
// Edit user // Edit user
$this->click('#usersWrapper .user-item:not(.me) .btn-edit'); $this->click('#usersWrapper .user-item:not(.me) .btn-edit');
$this->see('form.user-edit'); $this->see('form.user-edit')
$this->typeIn('form.user-edit input[name="email"]', 'bar@koel.net'); ->typeIn('form.user-edit input[name="email"]', 'bar@koel.net')
$this->enter(); ->enter()
$this->seeText('bar@koel.net', '#usersWrapper'); ->seeText('bar@koel.net', '#usersWrapper');
} }
} }

View file

@ -30,16 +30,40 @@ trait WebDriverShortcuts
return $selector; return $selector;
} }
/**
* Get a list of elements by a selector.
*
* @param $selector
*
* @return \Facebook\WebDriver\Remote\RemoteWebElement[]
*/
protected function els($selector) protected function els($selector)
{ {
return $this->driver->findElements(WebDriverBy::cssSelector($selector)); return $this->driver->findElements(WebDriverBy::cssSelector($selector));
} }
/**
* Type a string.
*
* @param $string
*
* @return $this
*/
protected function type($string) protected function type($string)
{ {
return $this->driver->getKeyboard()->sendKeys($string); $this->driver->getKeyboard()->sendKeys($string);
return $this;
} }
/**
* Type into an element.
*
* @param $element
* @param $string
*
* @return $this
*/
protected function typeIn($element, $string) protected function typeIn($element, $string)
{ {
$this->click($element)->clear(); $this->click($element)->clear();
@ -47,41 +71,80 @@ trait WebDriverShortcuts
return $this->type($string); return $this->type($string);
} }
/**
* Press a key.
*
* @param string $key
*
* @return $this
*/
protected function press($key = WebDriverKeys::ENTER) protected function press($key = WebDriverKeys::ENTER)
{ {
return $this->driver->getKeyboard()->pressKey($key); $this->driver->getKeyboard()->pressKey($key);
return $this;
} }
/**
* Press enter.
*
* @return $this
*/
protected function enter() protected function enter()
{ {
return $this->press(); return $this->press();
} }
/**
* Click an element.
*
* @param $element
*
* @return WebDriverElement
*/
protected function click($element) protected function click($element)
{ {
return $this->el($element)->click(); return $this->el($element)->click();
} }
/**
* Right-click an element.
*
* @param $element
*
* @return \Facebook\WebDriver\Remote\RemoteMouse
*/
protected function rightClick($element) protected function rightClick($element)
{ {
return $this->driver->getMouse()->contextClick($this->el($element)->getCoordinates()); return $this->driver->getMouse()->contextClick($this->el($element)->getCoordinates());
} }
/**
* Double-click and element.
*
* @param $element
*
* @return $this
*/
protected function doubleClick($element) protected function doubleClick($element)
{ {
$action = new WebDriverDoubleClickAction($this->driver->getMouse(), $this->el($element)); (new WebDriverDoubleClickAction($this->driver->getMouse(), $this->el($element)))->perform();
$action->perform(); return $this;
} }
/** /**
* Sleep (implicit wait) for some seconds. * Sleep (implicit wait) for some seconds.
* *
* @param $seconds * @param $seconds
*
* @return $this
*/ */
protected function sleep($seconds) protected function sleep($seconds)
{ {
$this->driver->manage()->timeouts()->implicitlyWait($seconds); $this->driver->manage()->timeouts()->implicitlyWait($seconds);
return $this;
} }
/** /**
@ -92,46 +155,102 @@ trait WebDriverShortcuts
* *
* @throws \Exception * @throws \Exception
* *
* @return mixed * @return $this
*/ */
protected function waitUntil($func, $timeout = 10) protected function waitUntil($func, $timeout = 10)
{ {
return $this->driver->wait($timeout)->until($func); $this->driver->wait($timeout)->until($func);
return $this;
} }
/**
* Wait and validate an element to be visible.
*
* @param $selector
*
* @return $this
*
* @throws \Exception
*/
public function see($selector) public function see($selector)
{ {
return $this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated( $this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated(
WebDriverBy::cssSelector($selector) WebDriverBy::cssSelector($selector)
)); ));
return $this;
} }
/**
* Wait and validate an element to be invisible.
*
* @param $selector string The element's CSS selector.
*
* @return $this
*
* @throws \Exception
*/
public function notSee($selector) public function notSee($selector)
{ {
return $this->waitUntil(WebDriverExpectedCondition::invisibilityOfElementLocated( $this->waitUntil(WebDriverExpectedCondition::invisibilityOfElementLocated(
WebDriverBy::cssSelector($selector) WebDriverBy::cssSelector($selector)
)); ));
return $this;
} }
/**
* Wait and validate a text to be visible in an element.
*
* @param $text
* @param $selector string The element's CSS selector.
*
* @return $this
* @throws \Exception
*/
public function seeText($text, $selector) public function seeText($text, $selector)
{ {
$this->waitUntil(WebDriverExpectedCondition::textToBePresentInElement( $this->waitUntil(WebDriverExpectedCondition::textToBePresentInElement(
WebDriverBy::cssSelector($selector), $text WebDriverBy::cssSelector($selector), $text
)); ));
return $this;
} }
/**
* Navigate back.
*
* @return $this
*/
protected function back() protected function back()
{ {
return $this->driver->navigate()->back(); $this->driver->navigate()->back();
return $this;
} }
/**
* Navigate forward.
*
* @return $this
*/
protected function forward() protected function forward()
{ {
return $this->driver->navigate()->forward(); $this->driver->navigate()->forward();
return $this;
} }
/**
* Refresh the page.
*
* @return $this
*/
protected function refresh() protected function refresh()
{ {
return $this->driver->navigate()->refresh(); $this->driver->navigate()->refresh();
return $this;
} }
} }

View file

@ -11,17 +11,17 @@ class ZSettingsScreenTest extends TestCase
{ {
public function testSettingsScreen() public function testSettingsScreen()
{ {
$this->loginAndGoTo('settings'); $this->loginAndGoTo('settings')
$this->typeIn('#inputSettingsPath', dirname(__DIR__.'/../songs')); ->typeIn('#inputSettingsPath', dirname(__DIR__.'/../songs'))
$this->enter(); ->enter()
// Wait for the page to reload // Wait for the page to reload
$this->waitUntil(function () { ->waitUntil(function () {
return $this->driver->executeScript('return document.readyState') === 'complete'; return $this->driver->executeScript('return document.readyState') === 'complete';
}); })
// And for the loading screen to disappear // And for the loading screen to disappear
$this->notSee('#overlay'); ->notSee('#overlay')
$this->goto('albums'); ->goto('albums')
// and make sure the scanning is good. // and make sure the scanning is good.
$this->seeText('Koel Testing Vol', '#albumsWrapper'); ->seeText('Koel Testing Vol', '#albumsWrapper');
} }
} }