mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
First steps in e2e
This commit is contained in:
parent
09ca3a4b9a
commit
ef618a611b
13 changed files with 523 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -66,3 +66,5 @@ Temporary Items
|
|||
### Sass ###
|
||||
.sass-cache/
|
||||
*.css.map
|
||||
|
||||
/database/e2e.sqlite
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Http;
|
|||
use App\Http\Middleware\Authenticate;
|
||||
use App\Http\Middleware\GetUserFromToken;
|
||||
use App\Http\Middleware\ObjectStorageAuthenticate;
|
||||
use App\Http\Middleware\UseDifferentConfigIfE2E;
|
||||
use Illuminate\Auth\Middleware\Authorize;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
|
||||
|
@ -20,6 +21,7 @@ class Kernel extends HttpKernel
|
|||
*/
|
||||
protected $middleware = [
|
||||
CheckForMaintenanceMode::class,
|
||||
UseDifferentConfigIfE2E::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
29
app/Http/Middleware/UseDifferentConfigIfE2E.php
Normal file
29
app/Http/Middleware/UseDifferentConfigIfE2E.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Check if the app is running in an E2E session and use the proper data settings.
|
||||
*/
|
||||
class UseDifferentConfigIfE2E
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($_SERVER['SERVER_PORT'] === '8081') {
|
||||
config(['database.default' => 'sqlite-e2e']);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,8 @@
|
|||
"barryvdh/laravel-ide-helper": "^2.1",
|
||||
"guzzlehttp/guzzle": "^6.1",
|
||||
"tymon/jwt-auth": "^0.5.6",
|
||||
"aws/aws-sdk-php-laravel": "^3.1"
|
||||
"aws/aws-sdk-php-laravel": "^3.1",
|
||||
"facebook/webdriver": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
|
@ -31,7 +32,8 @@
|
|||
},
|
||||
"autoload-dev": {
|
||||
"classmap": [
|
||||
"tests/TestCase.php"
|
||||
"tests/TestCase.php",
|
||||
"tests/E2E/TestCase.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
|
|
51
composer.lock
generated
51
composer.lock
generated
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "34d0eb369179b7e8718962fb530f83f0",
|
||||
"content-hash": "9c68d683b99bec01c5a9f55577399ae8",
|
||||
"hash": "9216fb1e8ef42422a945b1ebc83e902a",
|
||||
"content-hash": "9d176a92a6e8bf22d69a770843e8e013",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
|
@ -412,6 +412,53 @@
|
|||
],
|
||||
"time": "2015-11-06 14:35:42"
|
||||
},
|
||||
{
|
||||
"name": "facebook/webdriver",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/php-webdriver.git",
|
||||
"reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/af21de3ae5306a8ca0bcc02a19735dadc43e83f3",
|
||||
"reference": "af21de3ae5306a8ca0bcc02a19735dadc43e83f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": "^5.5 || ~7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^1.11",
|
||||
"php-mock/php-mock-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "4.6.* || ~5.0",
|
||||
"squizlabs/php_codesniffer": "^2.6"
|
||||
},
|
||||
"suggest": {
|
||||
"phpdocumentor/phpdocumentor": "2.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"description": "A PHP client for WebDriver",
|
||||
"homepage": "https://github.com/facebook/php-webdriver",
|
||||
"keywords": [
|
||||
"facebook",
|
||||
"php",
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2016-10-14 15:16:51"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.2.1",
|
||||
|
|
|
@ -52,6 +52,12 @@ return [
|
|||
'prefix' => '',
|
||||
],
|
||||
|
||||
'sqlite-e2e' => [
|
||||
'driver' => 'sqlite',
|
||||
'database' => __DIR__.'/../database/e2e.sqlite',
|
||||
'prefix' => '',
|
||||
],
|
||||
|
||||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'host' => env('DB_HOST', 'localhost'),
|
||||
|
|
|
@ -26,16 +26,16 @@ $factory->define(App\Models\Artist::class, function ($faker) {
|
|||
|
||||
$factory->define(App\Models\Album::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'name' => ucwords($faker->words(random_int(2, 5), true)),
|
||||
'cover' => md5(uniqid()).'.jpg',
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(App\Models\Song::class, function ($faker) {
|
||||
return [
|
||||
'title' => $faker->sentence,
|
||||
'title' => ucwords($faker->words(random_int(2, 5), true)),
|
||||
'length' => $faker->randomFloat(2, 10, 500),
|
||||
'track' => $faker->randomNumber(),
|
||||
'track' => random_int(1, 20),
|
||||
'lyrics' => $faker->paragraph(),
|
||||
'path' => '/tmp/'.uniqid().'.mp3',
|
||||
'mtime' => time(),
|
||||
|
|
25
database/seeds/E2EDataSeeder.php
Normal file
25
database/seeds/E2EDataSeeder.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Album;
|
||||
use App\Models\Artist;
|
||||
use App\Models\Song;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class E2EDataSeeder extends Seeder
|
||||
{
|
||||
private $sampleSongFullPath;
|
||||
public function run()
|
||||
{
|
||||
$this->sampleSongFullPath = realpath(__DIR__.'/../../tests/songs/full.mp3');
|
||||
|
||||
factory(Artist::class, 20)->create()->each(function(Artist $artist) {
|
||||
factory(Album::class, 5)->create([
|
||||
'artist_id' => $artist->id,
|
||||
])->each(function (Album $album) {
|
||||
factory(Song::class, 10)->create([
|
||||
'album_id' => $album->id,
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -63,6 +63,6 @@
|
|||
"scripts": {
|
||||
"postinstall": "cross-env NODE_ENV=production && gulp --production",
|
||||
"test": "mocha --compilers js:babel-register --require resources/assets/js/tests/helper.js resources/assets/js/tests/**/*Test.js",
|
||||
"e2e": "mocha resources/assets/js/tests/e2e/runner.js"
|
||||
"e2e": "echo 'remember to run `php artisan serve --port=8081`' && phpunit tests/e2e -c phpunit.e2e.xml"
|
||||
}
|
||||
}
|
||||
|
|
37
phpunit.e2e.xml
Normal file
37
phpunit.e2e.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="bootstrap/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="E2E Test Suite">
|
||||
<directory>./tests/e2e</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">app/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<php>
|
||||
<env name="APP_ENV" value="e2e"/>
|
||||
<env name="APP_KEY" value="16efa6c23c2e8c705826b0e66778fbe7"/>
|
||||
<env name="JWT_SECRET" value="ki8jSvMf5wFrlSRBAWcGbmAzBUJfc8p8"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
<env name="DB_CONNECTION" value="sqlite-e2e"/>
|
||||
<env name="LASTFM_API_KEY" value="foo"/>
|
||||
<env name="LASTFM_API_SECRET" value="bar"/>
|
||||
<env name="YOUTUBE_API_KEY" value="foo"/>
|
||||
<env name="ADMIN_EMAIL" value="koel@example.com"/>
|
||||
<env name="ADMIN_NAME" value="Koel Admin"/>
|
||||
<env name="ADMIN_PASSWORD" value="SoSecureK0el"/>
|
||||
<env name="BROADCAST_DRIVER" value="log"/>
|
||||
</php>
|
||||
</phpunit>
|
|
@ -11,6 +11,7 @@
|
|||
<testsuites>
|
||||
<testsuite name="Application Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
<exclude>./tests/e2e</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
|
|
174
tests/e2e/KoelTest.php
Normal file
174
tests/e2e/KoelTest.php
Normal file
|
@ -0,0 +1,174 @@
|
|||
<?php
|
||||
|
||||
namespace E2E;
|
||||
|
||||
use Facebook\WebDriver\Interactions\WebDriverActions;
|
||||
use Facebook\WebDriver\Remote\RemoteWebElement;
|
||||
use Facebook\WebDriver\WebDriverBy;
|
||||
use Facebook\WebDriver\WebDriverElement;
|
||||
use Facebook\WebDriver\WebDriverExpectedCondition;
|
||||
use Facebook\WebDriver\WebDriverKeys;
|
||||
|
||||
class KoelTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
static::assertContains('Koel', $this->driver->getTitle());
|
||||
|
||||
$formSelector = '#app > div.login-wrapper > form';
|
||||
|
||||
// Our login form should be there.
|
||||
static::assertCount(1, $this->els($formSelector));
|
||||
|
||||
// We submit rubbish and expect an error class on the form.
|
||||
$this->login('foo@bar.com', 'ThisIsWongOnSoManyLevels');
|
||||
$this->waitUntil(WebDriverExpectedCondition::presenceOfElementLocated(
|
||||
WebDriverBy::cssSelector("$formSelector.error")
|
||||
));
|
||||
|
||||
// Now we submit good stuff and make sure we're in.
|
||||
$this->login();
|
||||
$this->waitUntil(WebDriverExpectedCondition::textToBePresentInElement(
|
||||
WebDriverBy::cssSelector('#userBadge > a.view-profile.control > span'), 'Koel Admin'
|
||||
));
|
||||
|
||||
// Default URL must be Home
|
||||
static::assertEquals($this->url.'/#!/home', $this->driver->getCurrentURL());
|
||||
|
||||
// $this->_testSideBar();
|
||||
// $this->_testHomeScreen();
|
||||
return $this->_testQueueScreen();
|
||||
|
||||
// While we're at this, test logging out as well.
|
||||
$this->click('#userBadge > a.logout');
|
||||
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated(
|
||||
WebDriverBy::cssSelector($formSelector)
|
||||
));
|
||||
}
|
||||
|
||||
private function _testSideBar()
|
||||
{
|
||||
// All basic navigation
|
||||
foreach(['home', 'queue', 'songs', 'albums', 'artists', 'youtube', 'settings', 'users'] as $screen) {
|
||||
$this->goTo($screen);
|
||||
$this->waitUntil(function () use ($screen) {
|
||||
return $this->driver->getCurrentURL() === $this->url.'/#!/'.$screen;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private function _testHomeScreen()
|
||||
{
|
||||
$this->click('#sidebar a.home');
|
||||
|
||||
// We must see some greetings
|
||||
static::assertTrue($this->el('#homeWrapper > h1')->isDisplayed());
|
||||
|
||||
// 6 recently added albums
|
||||
static::assertCount(6, $this->els('#homeWrapper section.recently-added article'));
|
||||
|
||||
// 10 recently added songs
|
||||
static::assertCount(10, $this->els('#homeWrapper .recently-added-song-list .song-item-home'));
|
||||
|
||||
// Shuffle must work for latest albums
|
||||
$this->click('#homeWrapper section.recently-added article:nth-child(1) span.right a:nth-child(1)');
|
||||
static::assertCount(10, $this->els('#queueWrapper .song-list-wrap tr.song-item'));
|
||||
|
||||
$this->goTo('home');
|
||||
|
||||
$this->waitUntil(WebDriverExpectedCondition::visibilityOfElementLocated(
|
||||
WebDriverBy::cssSelector('#homeWrapper section.recently-added')
|
||||
));
|
||||
// Simulate a "double click to play" action
|
||||
/** @var $clickedSong RemoteWebElement */
|
||||
$clickedSong = $this->el('#homeWrapper section.recently-added > div > div:nth-child(2) li:nth-child(1) .details');
|
||||
$this->doubleClick($clickedSong);
|
||||
// The song must appear at the top of "Recently played" section
|
||||
/** @var $mostRecentSong RemoteWebElement */
|
||||
$mostRecentSong = $this->el('#homeWrapper .recently-added-song-list .song-item-home:nth-child(1) .details');
|
||||
static::assertEquals($mostRecentSong->getText(), $clickedSong->getText());
|
||||
}
|
||||
|
||||
private function _testQueueScreen()
|
||||
{
|
||||
$this->goTo('queue');
|
||||
static::assertContains('Current Queue', $this->el('#queueWrapper > h1 > span')->getText());
|
||||
|
||||
// Clear the queue
|
||||
$this->clearQueue();
|
||||
static::assertEmpty($this->els('#queueWrapper tr.song-item'));
|
||||
|
||||
// Go back to Albums and queue an album of 10 songs
|
||||
$this->goTo('albums');
|
||||
$this->click('#albumsWrapper > div > article:nth-child(1) > footer > p > span.right > a:nth-child(1)');
|
||||
|
||||
$this->goTo('queue');
|
||||
// Single song selection
|
||||
static::assertContains(
|
||||
'selected',
|
||||
$this->click('#queueWrapper tr.song-item:nth-child(1)')->getAttribute('class')
|
||||
);
|
||||
// shift+click
|
||||
(new WebDriverActions($this->driver))
|
||||
->keyDown(null, WebDriverKeys::SHIFT)
|
||||
->click($this->el('#queueWrapper tr.song-item:nth-child(5)'))
|
||||
->keyUp(null, WebDriverKeys::SHIFT)
|
||||
->perform();
|
||||
// should have 5 selected rows
|
||||
static::assertCount(5, $this->els('#queueWrapper tr.song-item.selected'));
|
||||
// Cmd+Click
|
||||
(new WebDriverActions($this->driver))
|
||||
->keyDown(null, WebDriverKeys::COMMAND)
|
||||
->click($this->el('#queueWrapper tr.song-item:nth-child(2)'))
|
||||
->click($this->el('#queueWrapper tr.song-item:nth-child(3)'))
|
||||
->keyUp(null, WebDriverKeys::COMMAND)
|
||||
->perform();
|
||||
// should have only 3 selected rows remaining
|
||||
static::assertCount(3, $this->els('#queueWrapper tr.song-item.selected'));
|
||||
// 2nd and 3rd rows must not be selected
|
||||
static::assertNotContains(
|
||||
'selected',
|
||||
$this->el('#queueWrapper tr.song-item:nth-child(2)')->getAttribute('class')
|
||||
);
|
||||
static::assertNotContains(
|
||||
'selected',
|
||||
$this->el('#queueWrapper tr.song-item:nth-child(3)')->getAttribute('class')
|
||||
);
|
||||
// Delete key should remove selected songs
|
||||
$this->press(WebDriverKeys::DELETE);
|
||||
$this->waitUntil(function () {
|
||||
return count($this->els('#queueWrapper tr.song-item.selected')) === 0
|
||||
&& count($this->els('#queueWrapper tr.song-item')) === 7;
|
||||
});
|
||||
|
||||
// Ctrl+A/Cmd+A should select all remaining songs
|
||||
(new WebDriverActions($this->driver))
|
||||
->keyDown(null, WebDriverKeys::COMMAND)
|
||||
->keyDown(null, 'A')
|
||||
->keyUp(null, 'A')
|
||||
->keyUp(null, WebDriverKeys::COMMAND)
|
||||
->perform();
|
||||
static::assertCount(7, $this->els('#queueWrapper tr.song-item.selected'));
|
||||
// Try adding these songs into a new playlist
|
||||
$this->click('#queueWrapper .buttons button.btn.btn-green');
|
||||
$this->typeIn('#queueWrapper .buttons input[type="text"]', 'Foo');
|
||||
$this->enter();
|
||||
$this->waitUntil(WebDriverExpectedCondition::textToBePresentInElement(
|
||||
WebDriverBy::cssSelector('#playlists > ul'), 'Foo'
|
||||
));
|
||||
|
||||
// Now go back to the queue and try adding a song into favorites
|
||||
$this->goTo('queue');
|
||||
/** @var WebDriverElement $firstSongInQueue */
|
||||
$firstSongInQueue = $this->el('#queueWrapper tr.song-item:nth-child(1) .title')->click();
|
||||
// TODO: There's a bug here.
|
||||
// After deleting, selection goes wrong (clicking first row selects second).
|
||||
var_dump($firstSongInQueue->getText());
|
||||
$this->click('#queueWrapper .buttons button.btn.btn-green');
|
||||
$this->click('#queueWrapper .buttons li:nth-child(1)');
|
||||
$this->goTo('favorites');
|
||||
var_dump($this->el('#favoritesWrapper tr.song-item:nth-last-child(1) .title')->getText());
|
||||
static::assertEquals($firstSongInQueue->getText(),
|
||||
$this->el('#favoritesWrapper tr.song-item:nth-last-child(1) .title')->getText());
|
||||
}
|
||||
}
|
190
tests/e2e/TestCase.php
Normal file
190
tests/e2e/TestCase.php
Normal file
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
|
||||
namespace E2E;
|
||||
|
||||
use App\Application;
|
||||
use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction;
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||
use Facebook\WebDriver\WebDriverBy;
|
||||
use Facebook\WebDriver\WebDriverDimension;
|
||||
use Facebook\WebDriver\WebDriverKeys;
|
||||
use Facebook\WebDriver\WebDriverPoint;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class TestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var RemoteWebDriver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* The default Koel URL for E2E (server by `php artisan serve --port=8081`).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $url = 'http://localhost:8081';
|
||||
protected $coverPath;
|
||||
|
||||
/**
|
||||
* TestCase constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->createApp();
|
||||
$this->prepareForE2E();
|
||||
$this->driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::chrome());
|
||||
$this->driver->manage()->window()->setPosition(new WebDriverPoint(0, 0))
|
||||
->setSize(new WebDriverDimension(1440, 900));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Application
|
||||
*/
|
||||
protected function createApp()
|
||||
{
|
||||
$this->app = require __DIR__.'/../../bootstrap/app.php';
|
||||
$this->app->make(Kernel::class)->bootstrap();
|
||||
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
private function prepareForE2E()
|
||||
{
|
||||
// Make sure we have a fresh database.
|
||||
@unlink(__DIR__.'/../../database/e2e.sqlite');
|
||||
touch(__DIR__.'/../../database/e2e.sqlite');
|
||||
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
Artisan::call('db:seed', ['--class' => 'E2EDataSeeder']);
|
||||
|
||||
if (!file_exists($this->coverPath)) {
|
||||
@mkdir($this->coverPath, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->driver->get($this->url);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
//$this->driver->quit();
|
||||
}
|
||||
|
||||
protected function el($selector)
|
||||
{
|
||||
return $this->driver->findElement(WebDriverBy::cssSelector($selector));
|
||||
}
|
||||
|
||||
protected function els($selector)
|
||||
{
|
||||
return $this->driver->findElements(WebDriverBy::cssSelector($selector));
|
||||
}
|
||||
|
||||
protected function type($string)
|
||||
{
|
||||
return $this->driver->getKeyboard()->sendKeys($string);
|
||||
}
|
||||
|
||||
protected function typeIn($element, $string)
|
||||
{
|
||||
if (is_string($element)) {
|
||||
$element = $this->el($element);
|
||||
}
|
||||
$element->click()->clear();
|
||||
|
||||
return $this->type($string);
|
||||
}
|
||||
|
||||
protected function press($key = WebDriverKeys::ENTER)
|
||||
{
|
||||
return $this->driver->getKeyboard()->pressKey($key);
|
||||
}
|
||||
|
||||
protected function enter()
|
||||
{
|
||||
return $this->press();
|
||||
}
|
||||
|
||||
protected function click($element)
|
||||
{
|
||||
return $this->el($element)->click();
|
||||
}
|
||||
|
||||
protected function doubleClick($element)
|
||||
{
|
||||
if (is_string($element)) {
|
||||
$element = $this->el($element);
|
||||
}
|
||||
$action = new WebDriverDoubleClickAction($this->driver->getMouse(), $element);
|
||||
|
||||
return $action->perform();
|
||||
}
|
||||
|
||||
protected function sleep($seconds)
|
||||
{
|
||||
$this->driver->manage()->timeouts()->implicitlyWait($seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until a condition is met.
|
||||
*
|
||||
* @param $func (closure|WebDriverExpectedCondition)
|
||||
* @param int $timeout
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function waitUntil($func, $timeout = 10)
|
||||
{
|
||||
return $this->driver->wait($timeout)->until($func);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log into Koel.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
protected function login($username = 'koel@example.com', $password = 'SoSecureK0el')
|
||||
{
|
||||
$this->typeIn("#app > div.login-wrapper > form > [type='email']", $username);
|
||||
$this->typeIn("#app > div.login-wrapper > form > [type='password']", $password);
|
||||
$this->enter();
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to allow going to a specific screen.
|
||||
*
|
||||
* @param $screen
|
||||
*
|
||||
* @return \Facebook\WebDriver\Remote\RemoteWebElement
|
||||
*/
|
||||
protected function goTo($screen)
|
||||
{
|
||||
if ($screen === 'favorites') {
|
||||
return $this->click('#sidebar .favorites a');
|
||||
} else {
|
||||
return $this->click("#sidebar a.$screen");
|
||||
}
|
||||
}
|
||||
|
||||
protected function clearQueue()
|
||||
{
|
||||
$this->goTo('queue');
|
||||
if ($this->els('#queueWrapper .song-item')) {
|
||||
$this->click('#queueWrapper > h1 > div > button.btn.btn-red');
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue