Skip to content

Commit

Permalink
Merge pull request #8 from jhoopes/dev-interactions
Browse files Browse the repository at this point in the history
Added few more APIs, database relation, browser width and code cleanup.
  • Loading branch information
Modelizer authored Sep 13, 2016
2 parents 8c030d2 + dd61f3f commit 1d298c0
Show file tree
Hide file tree
Showing 10 changed files with 550 additions and 24 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ composer require modelizer/selenium "~0.1"
Set configuration to your .env file.
```php
APP_URL="http://example.dev/" # If not set in .env file then http://localhost will be use as default
SELENIUM_WIDTH=1024 # If not set in the .env file, the default window width will be used
SELENIUM_HEIGHT=768 # If not set in the .env file, then the default window height will be used
```

Register Service provider in `app.php`
Expand Down
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
{
"name": "Mohammed Mudasir",
"email": "hello@mudasir.me"
},
{
"name": "John Hoopes",
"email": "john.hoopes@madisoncreativewb.com"
}
],
"require": {
Expand Down
7 changes: 7 additions & 0 deletions src/Exceptions/CannotClickElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Modelizer\Selenium\Exceptions;

class CannotClickElement extends \Exception
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/CannotFindElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Modelizer\Selenium\Exceptions;

class CannotFindElement extends \Exception
{
}
76 changes: 52 additions & 24 deletions src/SeleniumTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,79 @@
namespace Modelizer\Selenium;

use Modelizer\Selenium\Services\Application as Laravel;
use Modelizer\Selenium\Services\InteractWithPage as Interaction;
use Modelizer\Selenium\Services\ManageWindow;
use Modelizer\Selenium\Services\WaitForElement;
use Modelizer\Selenium\Services\WorkWithDatabase;
use PHPUnit_Extensions_Selenium2TestCase;

class SeleniumTestCase extends PHPUnit_Extensions_Selenium2TestCase
{
use Laravel;
use Laravel,
Interaction,
WorkWithDatabase,
WaitForElement,
ManageWindow;

/**
* @var string
*/
protected $baseUrl;

/**
* @var int
*/
protected $width;

/**
* @var int
*/
protected $height;

protected function setUp()
{
$this->setUpLaravel();

$this->setBrowserUrl(env('APP_URL', 'http://localhost/'));
$this->baseUrl = env('APP_URL', 'http://localhost/');
$this->setBrowserUrl($this->baseUrl);
$this->setBrowser(env('DEFAULT_BROWSER', 'chrome'));
}

protected function visit($path)
public function setupPage()
{
$this->url($path);

return $this;
}
if (empty($this->width)) {
$this->width = env('SELENIUM_WIDTH', 1024);
}

protected function see($text, $tag = 'html')
{
$this->assertContains($text, $this->byTag($tag)->text());
if (empty($this->height)) {
$this->height = env('SELENIUM_HEIGHT', 768);
}

return $this;
$this->changeWindowSize($this->width, $this->height);
}

protected function hold($seconds)
/**
* Force selenium to wait.
*
* @param int|float $seconds The number of seconds or partial seconds to wait
*
* @return $this
*/
protected function wait($seconds = 1)
{
sleep($seconds);
usleep($seconds * 1000000);

return $this;
}

protected function submitForm($inputs, $selector)
/**
* Alias for wait.
*
* @param int $seconds
*
* @return SeleniumTestCase
*/
public function hold($seconds = 1)
{
$form = $this->byCssSelector($selector);

foreach ($inputs as $input => $value) {
$form->byName($input)->value($value);
}

$form->submit();

return $this;
return $this->wait($seconds);
}
}
30 changes: 30 additions & 0 deletions src/Services/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Modelizer\Selenium\Services;

use Illuminate\Contracts\Auth\Authenticatable as UserContract;

trait Application
{
/**
Expand Down Expand Up @@ -63,4 +65,32 @@ protected function createApplication()

return $app;
}

/**
* Call artisan command and return code.
*
* @param string $command
* @param array $parameters
*
* @return int
*/
public function artisan($command, $parameters = [])
{
if (is_null($this->app)) {
return; // don't run when there is no application
}

return $this->code = $this->app['Illuminate\Contracts\Console\Kernel']->call($command, $parameters);
}

/**
* Set a user in laravel.
*
* @param UserContract $user
* @param null $driver
*/
public function be(UserContract $user, $driver = null)
{
$this->app['auth']->driver($driver)->setUser($user);
}
}
197 changes: 197 additions & 0 deletions src/Services/InteractWithPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php

namespace Modelizer\Selenium\Services;

trait InteractWithPage
{
/**
* Visit a URL within the browser.
*
* @param $path
*
* @return $this
*/
protected function visit($path)
{
$this->url($path);

return $this;
}

/**
* Scroll the page in the x-axis by the amount specified.
*
* @param $amount Positive values go down the page, negative values go up the page
*
* @return $this
*/
protected function scroll($amount)
{
$this->execute([
'script' => 'window.scrollBy(0, '.$amount.')',
'args' => [],
]);

return $this;
}

/**
* Assert that we see text within the specified tag
* Defaults to the body tag.
*
* @param $text
* @param string $tag
*
* @return $this
*/
protected function see($text, $tag = 'body')
{
$this->assertContains($text, $this->byTag($tag)->text());

return $this;
}

protected function notSee($text, $tag = 'body')
{
$this->assertNotContains($text, $this->byTag($tag)->text());
}

/**
* Assert the page is at the path that you specified.
*
* @param $path
*
* @return $this
*/
protected function seePageIs($path)
{
$this->assertEquals($this->baseUrl.$path, $this->url());

return $this;
}

/**
* Type a value into a form input by that inputs name.
*
* @param $value
* @param $name
* @param bool $clear Whether or not to clear the input first on say an edit form
*
* @return $this
*/
protected function type($value, $name, $clear = false)
{
$element = $this->findElement($name);

if ($clear) {
$element->clear();
}

$element->value($value);

return $this;
}

/**
* Function to type information as an array
* The key of the array specifies the input name.
*
* @param $information
* @param $clear
*
* @return $this
*/
protected function typeInformation($information, $clear = false)
{
foreach ($information as $element => $item) {
$this->type($item, $element, $clear);
}

return $this;
}

protected function submitForm($inputs, $selector)
{
$form = $this->byCssSelector($selector);
$this->type_information($inputs);
$form->submit();

return $this;
}

/**
* Press a button on the page that contains text.
*
* @param $text
*
* @return $this
*/
protected function press($text)
{
$this->findElement($text, "//button[contains(text(), '{$text}')]")->click();

return $this;
}

/**
* Click an element based on text passed in, or pass an Id or Name to find the element by.
*
* @param $textOrId
*
* @throws CannotClickElement Throws when the element cannot be clicked
*
* @return $this
*/
protected function click($textOrId)
{
$element = $this->findElement($textOrId, "//a[contains(text(), '{$textOrId}')]");

try {
$element->click();
} catch (\Exception $e) {
throw new CannotClickElement('Cannot click the element with the text: '.$textOrId);
}

return $this;
}

/**
* Will attempt to find an element by different patterns
* If xpath is provided, will attempt to find by that first.
*
* @param $value
* @param null $xpath
*
* @throws CannotFindElement
*
* @return \PHPUnit_Extensions_Selenium2TestCase_Element
*/
protected function findElement($value, $xpath = null)
{
$element = null;
try {
if (!is_null($xpath)) {
return $this->byXPath($xpath);
}
} catch (\Exception $e) {
}

try {
return $this->byId($value);
} catch (\Exception $e) {
}

try {
return $this->byName($value);
} catch (\Exception $e) {
}

try {
return $this->byCssSelector($value);
} catch (\Exception $e) {
}


throw new CannotFindElement('Cannot find element: '.$value.' isn\'t visible on the page');
}
}
Loading

0 comments on commit 1d298c0

Please sign in to comment.