Add basic browser tests for message menu and open in new window feature

pull/7169/head
Aleksander Machniak 4 years ago
parent a9abe62d58
commit 31b0275573

@ -142,6 +142,26 @@ class Browser extends \Laravel\Dusk\Browser
return !self::isPhone() && !self::isTablet();
}
/**
* Handler for actions that expect to open a new window
*
* @param callback $callback Function to execute with Browser object as argument
*
* @return array Main window handle and new window handle
*/
public function openWindow($callback)
{
$current_window = $this->driver->getWindowHandle();
$before_handles = $this->driver->getWindowHandles();
$callback($this);
$after_handles = $this->driver->getWindowHandles();
$new_window = reset(array_diff($after_handles, $before_handles));
return [$current_window, $new_window];
}
/**
* Change state of the Elastic's pretty checkbox
*/

@ -2,11 +2,11 @@
namespace Tests\Browser\Components;
use Laravel\Dusk\Component as BaseComponent;
use Laravel\Dusk\Component;
use PHPUnit\Framework\Assert;
use Tests\Browser\Browser;
class App extends BaseComponent
class App extends Component
{
/**
* Get the root selector for the component.
@ -46,10 +46,21 @@ class App extends BaseComponent
/**
* Assert value of rcmail.env entry
*
* @param Browser $browser Browser object
* @param array|string $key Env key name or array of key->expected pairs
* @param mixed $expected Expected value when $key is a string
*/
public function assertEnv($browser, string $key, $expected)
public function assertEnv($browser, $key, $expected = null)
{
Assert::assertEquals($expected, $this->getEnv($browser, $key));
if (is_array($key)) {
foreach ($key as $name => $expected) {
Assert::assertEquals($expected, $this->getEnv($browser, $name));
}
}
else {
Assert::assertEquals($expected, $this->getEnv($browser, $key));
}
}
/**
@ -69,10 +80,7 @@ class App extends BaseComponent
*/
public function getEnv($browser, $key)
{
$result = $browser->script("return rcmail.env['$key']");
$result = $result[0];
return $result;
return $browser->driver->executeScript("return rcmail.env['$key']");
}
/**
@ -80,10 +88,7 @@ class App extends BaseComponent
*/
public function getObjects($browser)
{
$objects = $browser->script("var i, r = []; for (i in rcmail.gui_objects) r.push(i); return r");
$objects = $objects[0];
return (array) $objects;
return (array) $browser->driver->executeScript("var i, r = []; for (i in rcmail.gui_objects) r.push(i); return r");
}
/**

@ -0,0 +1,119 @@
<?php
namespace Tests\Browser\Components;
use Tests\Browser\Browser;
use Laravel\Dusk\Component;
class Popupmenu extends Component
{
public $id;
/**
* Class constructor
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* Get the root selector for the component.
*
* @return string
*/
public function selector()
{
return '#' . $this->id;
}
/**
* Assert that the browser page contains the component.
*
* @param Browser $browser
*
* @return void
*/
public function assert($browser)
{
$browser->waitFor($this->selector());
}
/**
* Get the element shortcuts for the component.
*
* @return array
*/
public function elements()
{
return [
];
}
/**
* Assert popup menu state
*/
public function assertMenuState($browser, $active, $disabled = [], $missing = [])
{
foreach ($active as $option) {
// Print action is disabled on phones
if ($option == 'print' && $browser->isPhone()) {
$browser->assertMissing("a.print");
}
else {
$browser->assertVisible("a.{$option}:not(.disabled)");
}
}
foreach ($disabled as $option) {
if ($option == 'print' && $browser->isPhone()) {
$browser->assertMissing("a.print");
}
else {
$browser->assertVisible("a.{$option}.disabled");
}
}
foreach ($missing as $option) {
$browser->assertMissing("a.{$option}");
}
}
/**
* Close popup menu
*/
public function closeMenu($browser)
{
// hide the menu back
$browser->withinBody(function ($browser) {
$browser->script("window.UI.menu_hide('{$this->id}')");
$browser->waitUntilMissing($this->selector());
if ($browser->isPhone()) {
// FIXME: For some reason sometimes .popover-overlay does not close,
// we have to remove it manually
$browser->script(
"Array.from(document.getElementsByClassName('popover-overlay')).forEach(function(elem) { elem.parentNode.removeChild(elem); })"
);
}
});
}
/**
* Select popup menu item
*/
public function clickMenuItem($browser, $name, $dropdown_action = null)
{
$selector = "a.{$name}" . ($dropdown_action ? " + a.dropdown" : '');
$browser->click($selector);
if ($dropdown_action) {
$popup_id = $browser->attribute($selector, 'data-popup');
$browser->withinBody(function ($browser) use ($popup_id, $dropdown_action) {
$browser->click("#{$popup_id} li a.{$dropdown_action}");
});
}
$this->closeMenu($browser);
}
}

@ -3,9 +3,9 @@
namespace Tests\Browser\Components;
use Tests\Browser\Browser;
use Laravel\Dusk\Component as BaseComponent;
use Laravel\Dusk\Component;
class Taskmenu extends BaseComponent
class Taskmenu extends Component
{
protected $options = ['compose', 'mail', 'contacts', 'settings', 'about', 'logout'];

@ -3,9 +3,9 @@
namespace Tests\Browser\Components;
use Tests\Browser\Browser;
use Laravel\Dusk\Component as BaseComponent;
use Laravel\Dusk\Component;
class Toolbarmenu extends BaseComponent
class Toolbarmenu extends Component
{
/**
* Get the root selector for the component.

@ -3,6 +3,7 @@
namespace Tests\Browser\Mail;
use Tests\Browser\Components\App;
use Tests\Browser\Components\Popupmenu;
class Mail extends \Tests\Browser\TestCase
{
@ -53,4 +54,31 @@ class Mail extends \Tests\Browser\TestCase
$browser->assertTaskMenu('mail');
});
}
/**
* Test message menu
*/
public function testMessageMenu()
{
$this->browse(function ($browser) {
$browser->go('mail');
$browser->clickToolbarMenuItem('more');
$browser->with(new Popupmenu('message-menu'), function ($browser) {
// Note: These are button class names, not action names
$active = ['import'];
$disabled = ['print', 'download', 'edit.asnew', 'source', 'move', 'copy', 'extwin'];
$hidden = [];
if ($browser->isPhone()) {
$hidden = ['print', 'extwin'];
$disabled = array_diff($disabled, $hidden);
}
$browser->assertMenuState($active, $disabled, $hidden);
$browser->closeMenu();
});
});
}
}

@ -0,0 +1,70 @@
<?php
namespace Tests\Browser\Mail;
use Tests\Browser\Components\App;
use Tests\Browser\Components\Popupmenu;
class Open extends \Tests\Browser\TestCase
{
protected function setUp()
{
parent::setUp();
\bootstrap::init_imap();
\bootstrap::purge_mailbox('INBOX');
// import email messages
foreach (glob(TESTS_DIR . 'data/mail/list_00.eml') as $f) {
\bootstrap::import_message($f, 'INBOX');
}
}
/**
* Test Open in New Window action
*/
public function testOpenInNewWindow()
{
$this->browse(function ($browser) {
if ($browser->isPhone()) {
$this->markTestSkipped();
return;
}
$browser->go('mail');
$browser->waitFor('#messagelist tbody tr:first-child')
->ctrlClick('#messagelist tbody tr:first-child');
$browser->clickToolbarMenuItem('more');
$browser->with(new Popupmenu('message-menu'), function ($browser) {
$uids = $browser->driver->executeScript('return rcmail.message_list.get_selection()');
$this->assertCount(1, $uids);
$this->assertTrue(is_int($uids[0]) && $uids[0] > 0);
$uid = $uids[0];
list($current_window, $new_window) = $browser->openWindow(function ($browser) {
$browser->clickMenuItem('extwin');
});
$browser->driver->switchTo()->window($new_window);
$browser->with(new App(), function ($browser) use ($uid) {
$browser->assertEnv([
'task' => 'mail',
'action' => 'show',
'uid' => $uid,
]);
// TODO: werify the toolbar, which is different here than in the preview frame
});
$browser->driver->close();
$browser->driver->switchTo()->window($current_window);
});
});
}
}

@ -34,6 +34,7 @@ define('TESTS_PASS', $rcmail->config->get('tests_password'));
require_once(__DIR__ . '/Browser.php');
require_once(__DIR__ . '/TestCase.php');
require_once(__DIR__ . '/Components/App.php');
require_once(__DIR__ . '/Components/Popupmenu.php');
require_once(__DIR__ . '/Components/Taskmenu.php');
require_once(__DIR__ . '/Components/Toolbarmenu.php');

@ -25,6 +25,7 @@
<file>Mail/Compose.php</file>
<file>Mail/Getunread.php</file>
<file>Mail/List.php</file>
<file>Mail/Open.php</file>
</testsuite>
</testsuites>
</phpunit>

Loading…
Cancel
Save