Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F8198371
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
52 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/tests/Browser/Contacts/Contacts.php b/tests/Browser/Contacts/Contacts.php
index 76aef1750..b706074da 100644
--- a/tests/Browser/Contacts/Contacts.php
+++ b/tests/Browser/Contacts/Contacts.php
@@ -1,71 +1,83 @@
<?php
namespace Tests\Browser\Contacts;
class Contacts extends \Tests\Browser\DuskTestCase
{
protected function setUp()
{
parent::setUp();
\bootstrap::init_db();
}
/**
* Contacts UI Basics
*/
- public function testAddressbook()
+ public function testContactsUI()
{
$this->browse(function ($browser) {
$this->go('addressbook');
// check task
$this->assertEnvEquals('task', 'addressbook');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('qsearchbox', $objects);
$this->assertContains('folderlist', $objects);
$this->assertContains('contactslist', $objects);
$this->assertContains('countdisplay', $objects);
+ if (!$this->isDesktop()) {
+ $browser->assertMissing('#directorylist');
+ $browser->click('a.back-sidebar-button');
+ }
+
$browser->assertSeeIn('#layout-sidebar .header', 'Groups');
// Groups/Addressbooks list
$browser->assertVisible('#directorylist');
$browser->assertSeeIn('#directorylist li:first-child', 'Personal Addresses');
$browser->assertMissing('#directorylist .treetoggle.expanded');
// Contacts list
- $browser->assertVisible('#contacts-table');
+ if (!$this->isDesktop()) {
+ $browser->assertMissing('#contacts-table');
+ $browser->click('#directorylist li:first-child');
+ $browser->waitFor('#contacts-table');
+ }
+ else {
+ $browser->assertVisible('#contacts-table');
+ }
// Contacts list menu
- $browser->assertVisible('#toolbar-list-menu a.select:not(.disabled)');
+ if ($this->isPhone()) {
+ $this->assertToolbarMenu(['select'], []);
+ }
+ else if ($this->isTablet()) {
+ $browser->click('.toolbar-list-button');
+ $browser->assertVisible('#toolbar-list-menu a.select:not(.disabled)');
+ $browser->click();
+ }
+ else {
+ $browser->assertVisible('#toolbar-list-menu a.select:not(.disabled)');
+ }
// Toolbar menu
- $browser->with('#toolbar-menu', function($browser) {
- $browser->assertVisible('a.create:not(.disabled)');
- $browser->assertVisible('a.print.disabled');
- $browser->assertVisible('a.delete.disabled');
- $browser->assertVisible('a.search:not(.disabled)');
- $browser->assertVisible('a.import:not(.disabled)');
- $browser->assertVisible('a.export:not(.disabled)');
- $browser->assertVisible('a.more.disabled');
- });
+ $this->assertToolbarMenu(
+ ['create', 'search', 'import', 'export'], // active items
+ ['print', 'delete', 'more'], // inactive items
+ );
// Contact frame
- $browser->assertVisible('#contact-frame');
+ if (!$this->isPhone()) {
+ $browser->assertVisible('#contact-frame');
+ }
// Task menu
- $browser->with('#taskmenu', function($browser) {
- $browser->assertVisible('a.compose:not(.disabled):not(.selected)');
- $browser->assertVisible('a.mail:not(.disabled):not(.selected)');
- $browser->assertVisible('a.contacts.selected');
- $browser->assertVisible('a.settings:not(.disabled):not(.selected)');
- $browser->assertVisible('a.about:not(.disabled):not(.selected)');
- $browser->assertVisible('a.logout:not(.disabled):not(.selected)');
- });
+ $this->assertTaskMenu('contacts');
});
}
}
diff --git a/tests/Browser/Contacts/Import.php b/tests/Browser/Contacts/Import.php
index d7530a1fb..50514f23b 100644
--- a/tests/Browser/Contacts/Import.php
+++ b/tests/Browser/Contacts/Import.php
@@ -1,103 +1,103 @@
<?php
namespace Tests\Browser\Contacts;
class Import extends \Tests\Browser\DuskTestCase
{
/**
* Test basic elements of contacts import UI
*/
public function testImportUI()
{
$this->browse(function ($browser) {
$this->go('addressbook');
- $browser->click('#toolbar-menu a.import');
+ $this->clickToolbarMenuItem('import');
$browser->assertSeeIn('.ui-dialog-title', 'Import contacts');
$browser->assertVisible('.ui-dialog button.mainaction.import');
$browser->assertVisible('.ui-dialog button.cancel');
$browser->withinFrame('.ui-dialog iframe', function ($browser) {
// check task and action
$this->assertEnvEquals('task', 'addressbook');
$this->assertEnvEquals('action', 'import');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('importform', $objects);
$browser->assertSee('You can upload');
$browser->assertVisible('#rcmImportForm');
$browser->assertVisible('#rcmImportForm select');
$browser->assertVisible('#rcmImportForm .custom-switch');
// FIXME: selecting the file input directly does not work
$browser->assertVisible('#rcmImportForm .custom-file');
$browser->assertSelected('#rcmImportForm select', 0);
});
// Close the dialog
$browser->click('.ui-dialog button.cancel');
$browser->assertMissing('.ui-dialog');
});
}
/**
* Import contacts from a vCard file
*
* @depends testImportUI
*/
public function testImportProcess()
{
$this->browse(function ($browser) {
// Open the dialog again
- $browser->click('#toolbar-menu a.import');
+ $this->clickToolbarMenuItem('import');
$browser->assertSeeIn('.ui-dialog-title', 'Import contacts');
// Submit the form with no file attached
$browser->click('.ui-dialog button.mainaction');
$browser->waitForText('Attention');
$browser->assertSee('Please select a file');
$browser->driver->getKeyboard()->sendKeys(\Facebook\WebDriver\WebDriverKeys::ESCAPE);
$this->assertCount(1, $browser->elements('.ui-dialog'));
$browser->withinFrame('.ui-dialog iframe', function ($browser) {
$browser->attach('.custom-file input', TESTS_DIR . 'data/contacts.vcf');
});
$browser->click('.ui-dialog button.mainaction');
$browser->withinFrame('.ui-dialog iframe', function ($browser) {
$browser->waitForText('Successfully imported 2 contacts:');
});
// Close the dialog
$browser->click('.ui-dialog button.cancel');
// Expected existing contacts + imported
$browser->waitFor('#contacts-table tr');
$this->assertCount(4, $browser->elements('#contacts-table tbody tr'));
$browser->assertSeeIn('#rcmcountdisplay', '1 – 4 of 4');
});
}
/**
* Test imported contact
*
* @depends testImportProcess
*/
public function testImportResult()
{
$this->browse(function ($browser) {
// Open the dialog again
$browser->click('#contacts-table tr:last-child');
$browser->withinFrame('#contact-frame', function ($browser) {
$browser->waitFor('a.email'); // wait for iframe to load
$browser->assertSeeIn('.names', 'Sylvester Stalone');
$browser->assertSeeIn('a.email', 's.stalone@rambo.tv');
});
});
}
}
diff --git a/tests/Browser/DuskTestCase.php b/tests/Browser/DuskTestCase.php
index 67f7b936b..bb37242bc 100644
--- a/tests/Browser/DuskTestCase.php
+++ b/tests/Browser/DuskTestCase.php
@@ -1,263 +1,420 @@
<?php
namespace Tests\Browser;
use PHPUnit\Framework\TestCase;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Chrome\SupportsChrome;
use Laravel\Dusk\Concerns\ProvidesBrowser;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Process;
abstract class DuskTestCase extends TestCase
{
use ProvidesBrowser,
SupportsChrome;
protected $app;
protected static $phpProcess;
/**
* Prepare for Dusk test execution.
*
* @beforeClass
* @return void
*/
public static function prepare()
{
static::startWebServer();
static::startChromeDriver();
}
/**
* Create the RemoteWebDriver instance.
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
$options = (new ChromeOptions())->addArguments([
+ '--lang=en_US',
'--disable-gpu',
'--headless',
- '--window-size=1280,720',
]);
+ if (getenv('TESTS_MODE') == 'phone') {
+ // Fake User-Agent string for mobile mode
+ $ua = 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Mobile Safari/537.36';
+ $options->setExperimentalOption('mobileEmulation', ['userAgent' => $ua]);
+ $options->addArguments(['--window-size=375,667']);
+ }
+ else if (getenv('TESTS_MODE') == 'tablet') {
+ // Fake User-Agent string for mobile mode
+ $ua = 'Mozilla/5.0 (Linux; Android 6.0.1; vivo 1603 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36';
+ $options->setExperimentalOption('mobileEmulation', ['userAgent' => $ua]);
+ $options->addArguments(['--window-size=1024,768']);
+ }
+ else {
+ $options->addArguments(['--window-size=1280,720']);
+ }
+
return RemoteWebDriver::create(
'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
)
);
}
/**
* Set up the test run
*
* @return void
*/
protected function setUp()
{
parent::setUp();
$this->app = \rcmail::get_instance();
Browser::$baseUrl = 'http://localhost:8000';
Browser::$storeScreenshotsAt = __DIR__ . '/screenshots';
Browser::$storeConsoleLogAt = __DIR__ . '/console';
// This folder must exist in case Browser will try to write logs to it
if (!is_dir(Browser::$storeConsoleLogAt)) {
mkdir(Browser::$storeConsoleLogAt, 0777, true);
}
// Purge screenshots from the last test run
$pattern = sprintf('failure-%s_%s-*',
str_replace("\\", '_', get_class($this)),
$this->getName(false)
);
try {
$files = Finder::create()->files()->in(Browser::$storeScreenshotsAt)->name($pattern);
foreach ($files as $file) {
@unlink($file->getRealPath());
}
}
catch (\Symfony\Component\Finder\Exception\DirectoryNotFoundException $e) {
// ignore missing screenshots directory
}
// Purge console logs from the last test run
$pattern = sprintf('%s_%s-*',
str_replace("\\", '_', get_class($this)),
$this->getName(false)
);
try {
$files = Finder::create()->files()->in(Browser::$storeConsoleLogAt)->name($pattern);
foreach ($files as $file) {
@unlink($file->getRealPath());
}
}
catch (\Symfony\Component\Finder\Exception\DirectoryNotFoundException $e) {
// ignore missing screenshots directory
}
}
+ /**
+ * Check if in Phone mode
+ */
+ public static function isPhone()
+ {
+ return getenv('TESTS_MODE') == 'phone';
+ }
+
+ /**
+ * Check if in Tablet mode
+ */
+ public static function isTablet()
+ {
+ return getenv('TESTS_MODE') == 'tablet';
+ }
+
+ /**
+ * Check if in Desktop mode
+ */
+ public static function isDesktop()
+ {
+ return !self::isPhone() && !self::isTablet();
+ }
+
/**
* Assert specified rcmail.env value
*/
protected function assertEnvEquals($key, $expected)
{
$this->assertEquals($expected, $this->getEnv($key));
}
/**
* Assert specified checkbox state
*/
protected function assertCheckboxState($selector, $state)
{
$this->browse(function (Browser $browser) use ($selector, $state) {
if ($state) {
$browser->assertChecked($selector);
}
else {
$browser->assertNotChecked($selector);
}
});
}
+ /**
+ * Assert Task menu state
+ */
+ protected function assertTaskMenu($selected)
+ {
+ $this->browse(function (Browser $browser) use ($selected) {
+ // On phone the menu is invisible, open it
+ if ($this->isPhone()) {
+ $browser->click('.task-menu-button');
+ }
+
+ $browser->with('#taskmenu', function(Browser $browser) use ($selected) {
+ $options = ['compose', 'mail', 'contacts', 'settings', 'about', 'logout'];
+ foreach ($options as $option) {
+ $browser->assertVisible("a.{$option}:not(.disabled)" . ($selected == $option ? ".selected" : ":not(.selected)"));
+ }
+ });
+
+ // hide the menu back
+ if ($this->isPhone()) {
+ $browser->click('.popover a.button.cancel');
+ $browser->waitUntilMissing('#taskmenu');
+ }
+ });
+ }
+
+ /**
+ * Assert toolbar menu state
+ */
+ protected function assertToolbarMenu($active, $disabled)
+ {
+ $this->browse(function (Browser $browser) use ($active, $disabled) {
+ // On phone the menu is invisible, open it
+ if ($this->isPhone()) {
+ $browser->click('.toolbar-menu-button');
+ }
+
+ $browser->with('#toolbar-menu', function(Browser $browser) use ($active, $disabled) {
+ foreach ($active as $option) {
+ // Print action is disabled on phones
+ if ($option == 'print' && $this->isPhone()) {
+ $browser->assertMissing("a.print");
+ }
+ else {
+ $browser->assertVisible("a.{$option}:not(.disabled)");
+ }
+ }
+ foreach ($disabled as $option) {
+ if ($option == 'print' && $this->isPhone()) {
+ $browser->assertMissing("a.print");
+ }
+ else {
+ $browser->assertVisible("a.{$option}.disabled");
+ }
+ }
+ });
+
+ $this->closeToolbarMenu();
+ });
+ }
+
+ /**
+ * Close toolbar menu (on phones)
+ */
+ protected function closeToolbarMenu()
+ {
+ // hide the menu back
+ if ($this->isPhone()) {
+ $this->browse(function (Browser $browser) {
+ $browser->script("window.UI.menu_hide('toolbar-menu')");
+ $browser->waitUntilMissing('#toolbar-menu');
+ // 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 taskmenu item
+ */
+ protected function clickTaskMenuItem($name)
+ {
+ $this->browse(function (Browser $browser) use ($name) {
+ if ($this->isPhone()) {
+ $browser->click('.task-menu-button');
+ }
+
+ $browser->click("#taskmenu a.{$name}");
+
+ if ($this->isPhone()) {
+ $browser->waitUntilMissing('#taskmenu');
+ }
+ });
+ }
+
+ /**
+ * Select toolbar menu item
+ */
+ protected function clickToolbarMenuItem($name)
+ {
+ $this->browse(function (Browser $browser) use ($name) {
+ if ($this->isPhone()) {
+ $browser->click('.toolbar-menu-button');
+ }
+
+ $browser->click("#toolbar-menu a.{$name}");
+
+ if ($this->isPhone()) {
+ $this->closeToolbarMenu();
+// $browser->waitUntilMissing('#toolbar-menu');
+ }
+ });
+ }
+
/**
* Get content of rcmail.env entry
*/
protected function getEnv($key)
{
$this->browse(function (Browser $browser) use ($key, &$result) {
$result = $browser->script("return rcmail.env['$key']");
$result = $result[0];
});
return $result;
}
/**
* Get HTML IDs of defined buttons for specified Roundcube action
*/
protected function getButtons($action)
{
$this->browse(function (Browser $browser) use ($action, &$buttons) {
$buttons = $browser->script("return rcmail.buttons['$action']");
$buttons = $buttons[0];
});
if (is_array($buttons)) {
foreach ($buttons as $idx => $button) {
$buttons[$idx] = $button['id'];
}
}
return (array) $buttons;
}
/**
* Return names of defined gui_objects
*/
protected function getObjects()
{
$this->browse(function (Browser $browser) use (&$objects) {
$objects = $browser->script("var i, r = []; for (i in rcmail.gui_objects) r.push(i); return r");
$objects = $objects[0];
});
return (array) $objects;
}
/**
* Log in the test user
*/
protected function doLogin()
{
$this->browse(function (Browser $browser) {
$browser->type('_user', TESTS_USER);
$browser->type('_pass', TESTS_PASS);
$browser->click('button[type="submit"]');
// wait after successful login
//$browser->waitForReload();
$browser->waitUntil('!rcmail.busy');
});
}
/**
* Visit specified task/action with logon if needed
*/
protected function go($task = 'mail', $action = null, $login = true)
{
$this->browse(function (Browser $browser) use ($task, $action, $login) {
$browser->visit("/?_task=$task&_action=$action");
// check if we have a valid session
if ($login && $this->getEnv('task') == 'login') {
$this->doLogin();
}
});
}
/**
* Change state of the Elastic's pretty checkbox
*/
protected function setCheckboxState($selector, $state)
{
// Because you can't operate on the original checkbox directly
$this->browse(function (Browser $browser) use ($selector, $state) {
$browser->ensurejQueryIsAvailable();
if ($state) {
$run = "if (!element.prev().is(':checked')) element.click()";
}
else {
$run = "if (element.prev().is(':checked')) element.click()";
}
$browser->script(
"var element = jQuery('$selector')[0] || jQuery('input[name=$selector]')[0];"
."element = jQuery(element).next('.custom-control-label'); $run;"
);
});
}
/**
* Wait for UI (notice/confirmation/loading/error/warning) message
* and assert it's text
*/
protected function waitForMessage($type, $text)
{
$selector = '#messagestack > div.' . $type;
$this->browse(function ($browser) use ($selector, $text) {
$browser->waitFor($selector)->assertSeeIn($selector, $text);
});
}
/**
* Starts PHP server.
*/
protected static function startWebServer()
{
$path = realpath(__DIR__ . '/../../public_html');
$cmd = ['php', '-S', 'localhost:8000'];
$env = [];
static::$phpProcess = new Process($cmd, null, $env);
static::$phpProcess->setWorkingDirectory($path);
static::$phpProcess->start();
static::afterClass(function () {
static::$phpProcess->stop();
});
}
}
diff --git a/tests/Browser/Logout.php b/tests/Browser/Logout.php
index 4e563e264..c601ca887 100644
--- a/tests/Browser/Logout.php
+++ b/tests/Browser/Logout.php
@@ -1,25 +1,24 @@
<?php
namespace Tests\Browser;
class Logout extends DuskTestCase
{
public function testLogout()
{
$this->browse(function ($browser) {
$this->go('settings');
- // wait for the menu and then click the Logout button
- $browser->waitFor('#taskmenu');
- $browser->click('#taskmenu a.logout');
+ // click the Logout button in taskmenu
+ $this->clickTaskMenuItem('logout');
// task should be set to 'login'
$this->assertEnvEquals('task', 'login');
// form should exist
$browser->assertVisible('input[name="_user"]');
$browser->assertVisible('input[name="_pass"]');
$browser->assertMissing('#taskmenu');
});
}
}
diff --git a/tests/Browser/Mail/Compose.php b/tests/Browser/Mail/Compose.php
index b5a82c3c3..8b536aa9e 100644
--- a/tests/Browser/Mail/Compose.php
+++ b/tests/Browser/Mail/Compose.php
@@ -1,60 +1,64 @@
<?php
namespace Tests\Browser\Mail;
class Compose extends \Tests\Browser\DuskTestCase
{
public function testCompose()
{
$this->browse(function ($browser) {
$this->go('mail');
- $browser->click('#taskmenu a.compose');
+ $this->clickTaskMenuItem('compose');
// check task and action
$this->assertEnvEquals('task', 'mail');
$this->assertEnvEquals('action', 'compose');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('qsearchbox', $objects);
$this->assertContains('addressbookslist', $objects);
$this->assertContains('contactslist', $objects);
$this->assertContains('messageform', $objects);
$this->assertContains('attachmentlist', $objects);
$this->assertContains('filedrop', $objects);
$this->assertContains('uploadform', $objects);
// Toolbar menu
- $browser->with('#toolbar-menu', function($browser) {
- $browser->assertVisible('a.save.draft:not(.disabled)');
- $browser->assertVisible('a.attach:not(.disabled)');
- $browser->assertVisible('a.signature.disabled');
- $browser->assertVisible('a.responses:not(.disabled)');
- $browser->assertVisible('a.spellcheck:not(.disabled)');
- });
+ $this->assertToolbarMenu(
+ ['save.draft', 'responses', 'spellcheck'], // active items
+ ['signature'], // inactive items
+ );
+
+ if ($this->isPhone()) {
+ $this->assertToolbarMenu(['options'], []);
+ }
+ else {
+ $this->assertToolbarMenu(['attach'], []);
+ $browser->assertMissing('#toolbar-menu a.options');
+ }
// Task menu
- $browser->with('#taskmenu', function($browser) {
- $browser->assertVisible('a.compose:not(.disabled).selected');
- $browser->assertVisible('a.mail:not(.disabled):not(.selected)');
- $browser->assertVisible('a.contacts:not(.disabled):not(.selected)');
- $browser->assertVisible('a.settings:not(.disabled):not(.selected)');
- $browser->assertVisible('a.about:not(.disabled):not(.selected)');
- $browser->assertVisible('a.logout:not(.disabled):not(.selected)');
- });
+ $this->assertTaskMenu('compose');
// Header inputs
- $browser->assertSeeIn('#layout-sidebar .header', 'Options and attachments');
- $browser->assertVisible('#compose-attachments');
$browser->assertVisible('#_from');
$browser->assertVisible('#compose-subject');
$browser->assertInputValue('#compose-subject', '');
// Mail body input
$browser->assertVisible('#composebodycontainer.html-editor');
$browser->assertVisible('#composebodycontainer > textarea');
+
+ if ($this->isPhone()) {
+ $this->clickToolbarMenuItem('options');
+ }
+
+ // Compose options
+ $browser->assertSeeIn('#layout-sidebar .header', 'Options and attachments');
+ $browser->assertVisible('#compose-attachments');
});
}
}
diff --git a/tests/Browser/Mail/Getunread.php b/tests/Browser/Mail/Getunread.php
index e6300680c..2fa714bc8 100644
--- a/tests/Browser/Mail/Getunread.php
+++ b/tests/Browser/Mail/Getunread.php
@@ -1,37 +1,43 @@
<?php
namespace Tests\Browser\Mail;
class Getunread extends \Tests\Browser\DuskTestCase
{
protected $msgcount = 0;
protected function setUp()
{
parent::setUp();
\bootstrap::init_imap();
\bootstrap::purge_mailbox('INBOX');
// import email messages
foreach (glob(TESTS_DIR . 'data/mail/list_*.eml') as $f) {
\bootstrap::import_message($f, 'INBOX');
$this->msgcount++;
}
}
public function testGetunread()
{
$this->browse(function ($browser) {
$this->go('mail');
+ $browser->waitFor('#messagelist tbody tr');
+
+ // Messages list state
+ $this->assertCount($this->msgcount, $browser->elements('#messagelist tbody tr.unread'));
+
+ if (!$this->isDesktop()) {
+ $browser->click('.back-sidebar-button');
+ }
+
// Folders list state
- $browser->waitFor('.folderlist li.inbox.unread');
+ $browser->assertVisible('.folderlist li.inbox.unread');
$this->assertEquals(strval($this->msgcount), $browser->text('.folderlist li.inbox span.unreadcount'));
-
- // Messages list state
- $this->assertCount($this->msgcount, $browser->elements('#messagelist tr.unread'));
});
}
}
diff --git a/tests/Browser/Mail/List.php b/tests/Browser/Mail/List.php
index 333a4a5a0..183eb342f 100644
--- a/tests/Browser/Mail/List.php
+++ b/tests/Browser/Mail/List.php
@@ -1,77 +1,129 @@
<?php
namespace Tests\Browser\Mail;
class MailList extends \Tests\Browser\DuskTestCase
{
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');
}
}
public function testList()
{
$this->browse(function ($browser) {
$this->go('mail');
$this->assertCount(1, $browser->elements('#messagelist tbody tr'));
// check message list
$browser->assertVisible('#messagelist tbody tr:first-child.unread');
$this->assertEquals('Lines', $browser->text('#messagelist tbody tr:first-child span.subject'));
// Note: This element icon has width=0, use assertPresent() not assertVisible()
$browser->assertPresent('#messagelist tbody tr:first-child span.msgicon.unread');
// List toolbar menu
- $browser->assertVisible('#toolbar-list-menu a.select:not(.disabled)');
- $browser->assertVisible('#toolbar-list-menu a.options:not(.disabled)');
- $browser->assertVisible('a.toolbar-button.refresh:not(.disabled)');
+ $browser->assertVisible('#layout-list .header a.toolbar-button.refresh:not(.disabled)');
- $imap = \bootstrap::get_storage();
- if ($imap->get_threading()) {
- $browser->assertVisible('#toolbar-list-menu a.threads:not(.disabled)');
+ if ($this->isDesktop()) {
+ $browser->with('#toolbar-list-menu', function ($browser) {
+ $browser->assertVisible('a.select:not(.disabled)');
+ $browser->assertVisible('a.options:not(.disabled)');
+
+ $imap = \bootstrap::get_storage();
+ if ($imap->get_threading()) {
+ $browser->assertVisible('a.threads:not(.disabled)');
+ }
+ else {
+ $browser->assertMissing('a.threads');
+ }
+ });
}
- else {
- $browser->assertMissing('#toolbar-list-menu a.threads');
+ else if ($this->isTablet()) {
+ $browser->click('.toolbar-list-button');
+
+ $browser->with('#toolbar-list-menu', function ($browser) {
+ $browser->assertVisible('a.select:not(.disabled)');
+ $browser->assertVisible('a.options:not(.disabled)');
+
+ $imap = \bootstrap::get_storage();
+ if ($imap->get_threading()) {
+ $browser->assertVisible('a.threads:not(.disabled)');
+ }
+ else {
+ $browser->assertMissing('a.threads');
+ }
+ });
+
+ $browser->click(); // hide the popup menu
+ }
+ else { // phone
+ // On phones list options are in the toolbar menu
+ $browser->click('.toolbar-menu-button');
+
+ $browser->with('#toolbar-menu', function ($browser) {
+ $browser->assertVisible('a.select:not(.disabled)');
+ $browser->assertVisible('a.options:not(.disabled)');
+
+ $imap = \bootstrap::get_storage();
+ if ($imap->get_threading()) {
+ $browser->assertVisible('a.threads:not(.disabled)');
+ }
+ else {
+ $browser->assertMissing('a.threads');
+ }
+ });
+
+ $this->closeToolbarMenu();
}
});
}
/**
* @depends testList
*/
public function testListSelection()
{
$this->browse(function ($browser) {
- $browser->click('#toolbar-list-menu a.select');
- $browser->assertFocused('#toolbar-list-menu a.select');
+ if ($this->isPhone()) {
+ $browser->click('.toolbar-menu-button');
+ $browser->click('#toolbar-menu a.select');
+ }
+ else if ($this->isTablet()) {
+ $browser->click('.toolbar-list-button');
+ $browser->click('#toolbar-list-menu a.select');
+ }
+ else {
+ $browser->click('#toolbar-list-menu a.select');
+ $browser->assertFocused('#toolbar-list-menu a.select');
+ }
// Popup menu content
$browser->with('#listselect-menu', function($browser) {
$browser->assertVisible('a.selection:not(.disabled)');
$browser->assertVisible('a.select.all:not(.disabled)');
$browser->assertVisible('a.select.page:not(.disabled)');
$browser->assertVisible('a.select.unread:not(.disabled)');
$browser->assertVisible('a.select.flagged:not(.disabled)');
$browser->assertVisible('a.select.invert:not(.disabled)');
$browser->assertVisible('a.select.none:not(.disabled)');
});
- // Close the menu by clicking the page body
+ // Close the menu(s) by clicking the page body
$browser->click();
$browser->waitUntilMissing('#listselect-menu');
// TODO: Test selection actions
});
}
}
diff --git a/tests/Browser/Mail/Mail.php b/tests/Browser/Mail/Mail.php
index 894a72134..64cff0f96 100644
--- a/tests/Browser/Mail/Mail.php
+++ b/tests/Browser/Mail/Mail.php
@@ -1,55 +1,53 @@
<?php
namespace Tests\Browser\Mail;
class Mail extends \Tests\Browser\DuskTestCase
{
public function testMailUI()
{
$this->browse(function ($browser) {
$this->go('mail');
// check task
$this->assertEnvEquals('task', 'mail');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('qsearchbox', $objects);
$this->assertContains('mailboxlist', $objects);
$this->assertContains('messagelist', $objects);
$this->assertContains('quotadisplay', $objects);
$this->assertContains('search_filter', $objects);
$this->assertContains('countdisplay', $objects);
+ if (!$this->isDesktop()) {
+ $browser->click('.back-sidebar-button');
+ }
+
$browser->assertSeeIn('#layout-sidebar .header', TESTS_USER);
// Folders list
$browser->assertVisible('#mailboxlist li.mailbox.inbox.selected');
+ if (!$this->isDesktop()) {
+ $browser->click('.back-list-button');
+ }
+
// Mail preview frame
- $browser->assertVisible('#messagecontframe');
+ if (!$this->isPhone()) {
+ $browser->assertVisible('#messagecontframe');
+ }
// Toolbar menu
- $browser->with('#toolbar-menu', function($browser) {
- $browser->assertMissing('a.compose'); // this is always hidden button
- $browser->assertVisible('a.reply.disabled');
- $browser->assertVisible('a.reply-all.disabled');
- $browser->assertVisible('a.forward.disabled');
- $browser->assertVisible('a.delete.disabled');
- $browser->assertVisible('a.markmessage.disabled');
- $browser->assertVisible('a.more:not(.disabled)');
- });
+ $this->assertToolbarMenu(
+ ['more'], // active items
+ ['reply', 'reply-all', 'forward', 'delete', 'markmessage'], // inactive items
+ );
// Task menu
- $browser->with('#taskmenu', function($browser) {
- $browser->assertVisible('a.compose:not(.disabled):not(.selected)');
- $browser->assertVisible('a.mail.selected');
- $browser->assertVisible('a.contacts:not(.disabled):not(.selected)');
- $browser->assertVisible('a.settings:not(.disabled):not(.selected)');
- $browser->assertVisible('a.about:not(.disabled):not(.selected)');
- $browser->assertVisible('a.logout:not(.disabled):not(.selected)');
- });
+ $this->assertTaskMenu('mail');
});
}
}
diff --git a/tests/Browser/Settings/About.php b/tests/Browser/Settings/About.php
index 73c7df56a..5d065653d 100644
--- a/tests/Browser/Settings/About.php
+++ b/tests/Browser/Settings/About.php
@@ -1,27 +1,27 @@
<?php
namespace Tests\Browser\Settings;
class About extends \Tests\Browser\DuskTestCase
{
public function testAbout()
{
$this->browse(function ($browser) {
$this->go('settings');
- $browser->click('#taskmenu a.about');
+ $this->clickTaskMenuItem('about');
$browser->assertSeeIn('.ui-dialog-title', 'About');
$browser->assertVisible('.ui-dialog #aboutframe');
$browser->withinFrame('#aboutframe', function ($browser) {
// check task and action
$this->assertEnvEquals('task', 'settings');
$this->assertEnvEquals('action', 'about');
$browser->assertSee($this->app->config->get('product_name'));
$browser->assertVisible('#pluginlist');
});
});
}
}
diff --git a/tests/Browser/Settings/Folders.php b/tests/Browser/Settings/Folders.php
index 549922460..ca3ccff1a 100644
--- a/tests/Browser/Settings/Folders.php
+++ b/tests/Browser/Settings/Folders.php
@@ -1,33 +1,33 @@
<?php
namespace Tests\Browser\Settings;
class Folders extends \Tests\Browser\DuskTestCase
{
public function testFolders()
{
$this->browse(function ($browser) {
$this->go('settings', 'folders');
// task should be set to 'settings' and action to 'folders'
$this->assertEnvEquals('task', 'settings');
$this->assertEnvEquals('action', 'folders');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('quotadisplay', $objects);
$this->assertContains('subscriptionlist', $objects);
- $browser->assertVisible('#settings-menu li.folders.selected');
+ if ($this->isDesktop()) {
+ $browser->assertVisible('#settings-menu li.folders.selected');
+ }
// Folders list
$browser->assertVisible('#subscription-table li.mailbox.inbox');
// Toolbar menu
- $browser->assertVisible('#toolbar-menu a.create:not(.disabled)');
- $browser->assertVisible('#toolbar-menu a.delete.disabled');
- $browser->assertVisible('#toolbar-menu a.purge.disabled');
+ $this->assertToolbarMenu(['create'], ['delete', 'purge']);
});
}
}
diff --git a/tests/Browser/Settings/Identities.php b/tests/Browser/Settings/Identities.php
index f3e3fd701..62c95e80c 100644
--- a/tests/Browser/Settings/Identities.php
+++ b/tests/Browser/Settings/Identities.php
@@ -1,32 +1,33 @@
<?php
namespace Tests\Browser\Settings;
class Identities extends \Tests\Browser\DuskTestCase
{
public function testIdentities()
{
$this->browse(function ($browser) {
$this->go('settings', 'identities');
// check task and action
$this->assertEnvEquals('task', 'settings');
$this->assertEnvEquals('action', 'identities');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('identitieslist', $objects);
- $browser->assertVisible('#settings-menu li.identities.selected');
+ if ($this->isDesktop()) {
+ $browser->assertVisible('#settings-menu li.identities.selected');
+ }
// Identities list
$browser->assertVisible('#identities-table tr:first-child.focused');
$browser->assertSeeIn('#identities-table tr:first-child td.mail', TESTS_USER);
// Toolbar menu
- $browser->assertVisible('#toolbar-menu a.create:not(.disabled)');
- $browser->assertVisible('#toolbar-menu a.delete.disabled');
+ $this->assertToolbarMenu(['create'], ['delete']);
});
}
}
diff --git a/tests/Browser/Settings/Preferences.php b/tests/Browser/Settings/Preferences.php
index 2143eae6c..bb9a1fc48 100644
--- a/tests/Browser/Settings/Preferences.php
+++ b/tests/Browser/Settings/Preferences.php
@@ -1,30 +1,37 @@
<?php
namespace Tests\Browser\Settings;
class Preferences extends \Tests\Browser\DuskTestCase
{
public function testPreferences()
{
$this->browse(function ($browser) {
$this->go('settings');
$objects = $this->getObjects();
$this->assertContains('sectionslist', $objects);
$browser->assertVisible('#settings-menu li.preferences.selected');
+ // On phone/tablet #sections-table is initially hidden
+ if ($this->isPhone() || $this->isTablet()) {
+ $browser->assertMissing('#sections-table');
+ $browser->click('#settings-menu li.preferences');
+ $browser->waitFor('#sections-table');
+ }
+
// Preferences actions
$browser->with('#sections-table', function($browser) {
$browser->assertSeeIn('tr.general', 'User Interface');
$browser->assertSeeIn('tr.mailbox', 'Mailbox View');
$browser->assertSeeIn('tr.mailview', 'Displaying Messages');
$browser->assertSeeIn('tr.compose', 'Composing Messages');
$browser->assertSeeIn('tr.addressbook', 'Contacts');
$browser->assertSeeIn('tr.folders', 'Special Folders');
$browser->assertSeeIn('tr.server', 'Server Settings');
});
});
}
}
diff --git a/tests/Browser/Settings/Preferences/General.php b/tests/Browser/Settings/Preferences/General.php
index 34a140a3b..24b4f77b9 100644
--- a/tests/Browser/Settings/Preferences/General.php
+++ b/tests/Browser/Settings/Preferences/General.php
@@ -1,144 +1,163 @@
<?php
namespace Tests\Browser\Settings\Preferences;
class General extends \Tests\Browser\DuskTestCase
{
protected function tearDown()
{
parent::tearDown();
// Reset user preferences back to defaults
$db = $this->app->get_dbh();
$db->query("UPDATE users SET preferences = '' WHERE username = ?", TESTS_USER);
}
public function testGeneral()
{
$this->browse(function ($browser) {
$this->go('settings');
- $browser->click('#sections-table tr.general');
+ if ($this->isPhone() || $this->isTablet()) {
+ $browser->click('#settings-menu li.preferences');
+ $browser->waitFor('#sections-table');
+ }
$browser->assertVisible('#sections-table tr.general.focused');
+ $browser->click('#sections-table tr.general');
+
+ if ($this->isPhone()) {
+ $browser->waitFor('#layout-content .footer a.button.submit:not(.disabled)');
+ $browser->assertVisible('#layout-content .footer a.button.prev.disabled');
+ $browser->assertVisible('#layout-content .footer a.button.next:not(.disabled)');
+ }
+
$browser->withinFrame('#preferences-frame', function ($browser) {
- $browser->waitFor('.formbuttons button.submit');
+ if (!$this->isPhone()) {
+ $browser->waitFor('.formbuttons button.submit');
+ }
// check task and action
$this->assertEnvEquals('task', 'settings');
$this->assertEnvEquals('action', 'edit-prefs');
// Main Options fieldset
$browser->with('form.propform fieldset.main', function ($browser) {
$browser->assertSeeIn('legend', 'Main Options');
$browser->assertSeeIn('label[for=rcmfd_lang]', 'Language');
$browser->assertVisible('select[name=_language]');
$browser->assertSelected('select[name=_language]', 'en_US');
$browser->assertSeeIn('label[for=rcmfd_timezone]', 'Time zone');
$browser->assertVisible('select[name=_timezone]');
// we don't know what timezone has been autodetected
// $browser->assertSelected('select[name=_timezone]', 'auto');
$browser->assertSeeIn('label[for=rcmfd_time_format]', 'Time format');
$browser->assertVisible('select[name=_time_format]');
$browser->assertSelected('select[name=_time_format]', $this->app->config->get('time_format'));
$browser->assertSeeIn('label[for=rcmfd_date_format]', 'Date format');
$browser->assertVisible('select[name=_date_format]');
$browser->assertSelected('select[name=_date_format]', $this->app->config->get('date_format'));
$browser->assertSeeIn('label[for=rcmfd_prettydate]', 'Pretty dates');
$this->assertCheckboxState('_pretty_date', $this->app->config->get('prettydate'));
$browser->assertSeeIn('label[for=rcmfd_displaynext]', 'Display next');
$this->assertCheckboxState('_display_next', $this->app->config->get('display_next'));
$browser->assertSeeIn('label[for=rcmfd_refresh_interval]', 'Refresh');
$browser->assertVisible('select[name=_refresh_interval]');
$browser->assertSelected('select[name=_refresh_interval]', $this->app->config->get('refresh_interval')/60);
});
// Interface Skin fieldset
$browser->with('form.propform fieldset.skin', function ($browser) {
$browser->assertSeeIn('legend', 'Interface skin');
// TODO
});
// Browser Options fieldset
$browser->with('form.propform fieldset.browser', function ($browser) {
$browser->assertSeeIn('legend', 'Browser Options');
$browser->assertSeeIn('label[for=rcmfd_standard_windows]', 'Handle popups');
$this->assertCheckboxState('_standard_windows', $this->app->config->get('standard_windows'));
});
});
});
}
/**
* Test (all) User Interface preferences change
*
* @depends testGeneral
*/
public function testPreferencesChange()
{
// Values we're changing to
// TODO: Skin or language change causes page reload, we should test this separately
$this->settings = [
'timezone' => 'Pacific/Midway',
'time_format' => 'h:i A',
'date_format' => 'd-m-Y',
'refresh_interval' => 60,
'pretty_date' => !boolval($this->app->config->get('prettydate')),
'display_next' => !boolval($this->app->config->get('display_next')),
'standard_windows' => !boolval($this->app->config->get('standard_windows')),
];
$this->browse(function ($browser) {
// Update preferences
$browser->withinFrame('#preferences-frame', function ($browser) {
$browser->select('_timezone', $this->settings['timezone']);
$browser->select('_time_format', $this->settings['time_format']);
$browser->select('_date_format', $this->settings['date_format']);
$browser->select('_refresh_interval', $this->settings['refresh_interval']);
$this->setCheckboxState('_pretty_date', $this->settings['pretty_date']);
$this->setCheckboxState('_display_next', $this->settings['display_next']);
$this->setCheckboxState('_standard_windows', $this->settings['standard_windows']);
// Submit form
- $browser->click('.formbuttons button.submit');
+ if (!$this->isPhone()) {
+ $browser->click('.formbuttons button.submit');
+ }
});
+ if ($this->isPhone()) {
+ $browser->click('#layout-content .footer a.submit');
+ }
+
$this->waitForMessage('confirmation', 'Successfully saved');
// Verify if every option has been updated
$browser->withinFrame('#preferences-frame', function ($browser) {
$browser->assertSelected('_timezone', $this->settings['timezone']);
$browser->assertSelected('_time_format', $this->settings['time_format']);
$browser->assertSelected('_date_format', $this->settings['date_format']);
$browser->assertSelected('_refresh_interval', $this->settings['refresh_interval']);
$this->assertCheckboxState('_pretty_date', $this->settings['pretty_date']);
$this->assertCheckboxState('_display_next', $this->settings['display_next']);
$this->assertCheckboxState('_standard_windows', $this->settings['standard_windows']);
// Assert the options have been saved in database properly
$prefs = \bootstrap::get_prefs();
$options = array_diff(array_keys($this->settings), ['refresh_interval', 'pretty_date']);
foreach ($options as $option) {
$this->assertEquals($this->settings[$option], $prefs[$option]);
}
$this->assertEquals($this->settings['pretty_date'], $prefs['prettydate']);
$this->assertEquals($this->settings['refresh_interval'], $prefs['refresh_interval']/60);
});
});
}
}
diff --git a/tests/Browser/Settings/Responses.php b/tests/Browser/Settings/Responses.php
index 9de267aef..5c3a09501 100644
--- a/tests/Browser/Settings/Responses.php
+++ b/tests/Browser/Settings/Responses.php
@@ -1,32 +1,33 @@
<?php
namespace Tests\Browser\Settings;
class Responses extends \Tests\Browser\DuskTestCase
{
public function testIdentities()
{
$this->browse(function ($browser) {
$this->go('settings', 'responses');
// check task and action
$this->assertEnvEquals('task', 'settings');
$this->assertEnvEquals('action', 'responses');
$objects = $this->getObjects();
// these objects should be there always
$this->assertContains('responseslist', $objects);
- $browser->assertVisible('#settings-menu li.responses.selected');
+ if ($this->isDesktop()) {
+ $browser->assertVisible('#settings-menu li.responses.selected');
+ }
// Responses list
$browser->assertPresent('#responses-table');
$browser->assertMissing('#responses-table tr');
// Toolbar menu
- $browser->assertVisible('#toolbar-menu a.create:not(.disabled)');
- $browser->assertVisible('#toolbar-menu a.delete.disabled');
+ $this->assertToolbarMenu(['create'], ['delete']);
});
}
}
diff --git a/tests/Browser/Settings/Settings.php b/tests/Browser/Settings/Settings.php
index d19d4e7e7..a5fd9d889 100644
--- a/tests/Browser/Settings/Settings.php
+++ b/tests/Browser/Settings/Settings.php
@@ -1,36 +1,29 @@
<?php
namespace Tests\Browser\Settings;
class Settings extends \Tests\Browser\DuskTestCase
{
public function testSettings()
{
$this->browse(function ($browser) {
$this->go('settings');
// task should be set to 'settings'
$this->assertEnvEquals('task', 'settings');
$browser->assertSeeIn('#layout-sidebar .header', 'Settings');
// Sidebar menu
$browser->with('#settings-menu', function($browser) {
$browser->assertSeeIn('li.preferences', 'Preferences');
$browser->assertSeeIn('li.folders', 'Folders');
$browser->assertSeeIn('li.identities', 'Identities');
$browser->assertSeeIn('li.responses', 'Responses');
});
// Task menu
- $browser->with('#taskmenu', function($browser) {
- $browser->assertVisible('a.compose:not(.disabled):not(.selected)');
- $browser->assertVisible('a.mail:not(.disabled):not(.selected)');
- $browser->assertVisible('a.contacts:not(.disabled):not(.selected)');
- $browser->assertVisible('a.settings:not(.disabled).selected');
- $browser->assertVisible('a.about:not(.disabled):not(.selected)');
- $browser->assertVisible('a.logout:not(.disabled):not(.selected)');
- });
+ $this->assertTaskMenu('settings');
});
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jul 8, 7:10 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1051839
Default Alt Text
(52 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment