diff --git a/tests/Browser/Components/HtmlEditor.php b/tests/Browser/Components/HtmlEditor.php
new file mode 100644
index 000000000..40d71a393
--- /dev/null
+++ b/tests/Browser/Components/HtmlEditor.php
@@ -0,0 +1,97 @@
+id = trim($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() . '.html-editor');
+ }
+
+ /**
+ * Get the element shortcuts for the component.
+ *
+ * @return array
+ */
+ public function elements()
+ {
+ return [
+ '@plain-toolbar' => '.editor-toolbar',
+ '@plain-body' => 'textarea',
+ '@html-editor' => '.mce-tinymce',
+ '@html-toolbar' => '.mce-tinymce .mce-toolbar',
+ '@html-body' => 'iframe',
+ ];
+ }
+
+ /**
+ * Assert editor mode
+ */
+ public function assertMode($browser, $mode)
+ {
+ if ($mode == self::MODE_PLAIN) {
+ $browser->assertVisible('@plain-toolbar')
+ ->assertMissing('@html-body');
+ }
+ else {
+ $browser->assertMissing('@plain-toolbar')
+ ->assertVisible('@html-body');
+ }
+ }
+
+ /**
+ * Switch editor mode
+ */
+ public function switchMode($browser, $mode, $accept_warning = false)
+ {
+ if ($mode == self::MODE_HTML) {
+ $browser->click('@plain-toolbar a.mce-i-html');
+ if ($accept_warning) {
+ $browser->waitForDialog()->acceptDialog();
+ }
+ $browser->waitFor('@html-body');
+ }
+ else {
+ $browser->click('@html-toolbar .mce-i-plaintext');
+ if ($accept_warning) {
+ $browser->waitForDialog()->acceptDialog();
+ }
+ $browser->waitFor('@plain-body');
+ }
+ }
+}
diff --git a/tests/Browser/Mail/ComposeTest.php b/tests/Browser/Mail/ComposeTest.php
index b9b8812c6..a61025837 100644
--- a/tests/Browser/Mail/ComposeTest.php
+++ b/tests/Browser/Mail/ComposeTest.php
@@ -2,7 +2,9 @@
namespace Tests\Browser\Mail;
+use Facebook\Webdriver\WebDriverKeys;
use Tests\Browser\Components\App;
+use Tests\Browser\Components\HtmlEditor;
class ComposeTest extends \Tests\Browser\TestCase
{
@@ -65,4 +67,35 @@ class ComposeTest extends \Tests\Browser\TestCase
$browser->assertVisible('#compose-attachments');
});
}
+
+ /**
+ * depends @testCompose
+ */
+ function testPlainEditor()
+ {
+ // Test for #7230: Shift+PageUp text selection
+ // and copy-pasting with keyboard
+ $this->browse(function ($browser) {
+ $browser->with(new HtmlEditor('composebodycontainer'), function ($browser) {
+ $browser->assertMode(HtmlEditor::MODE_PLAIN)
+ ->type('@plain-body', "line1\nline2\n")
+ ->keys('@plain-body', [WebDriverKeys::SHIFT, WebDriverKeys::PAGE_UP])
+ ->keys('@plain-body', [WebDriverKeys::CONTROL, 'c'])
+ ->keys('@plain-body', [WebDriverKeys::CONTROL, 'x'])
+ ->keys('@plain-body', [WebDriverKeys::CONTROL, 'v'])
+ ->keys('@plain-body', [WebDriverKeys::CONTROL, 'v'])
+ ->assertValue('@plain-body', "line1\nline2\nline1\nline2\n");
+ });
+ });
+
+ // Test switching to HTML and back
+ $this->browse(function ($browser) {
+ $browser->with(new HtmlEditor('composebodycontainer'), function ($browser) {
+ $browser->switchMode(HtmlEditor::MODE_HTML, true)
+ ->switchMode(HtmlEditor::MODE_PLAIN)
+ ->assertValue('@plain-body', "line1\nline2\nline1\nline2")
+ ->switchMode(HtmlEditor::MODE_HTML, false);
+ });
+ });
+ }
}
diff --git a/tests/Browser/bootstrap.php b/tests/Browser/bootstrap.php
index 23442da68..01244d2d5 100644
--- a/tests/Browser/bootstrap.php
+++ b/tests/Browser/bootstrap.php
@@ -38,6 +38,7 @@ require_once(__DIR__ . '/Browser.php');
require_once(__DIR__ . '/TestCase.php');
require_once(__DIR__ . '/Components/App.php');
require_once(__DIR__ . '/Components/Dialog.php');
+require_once(__DIR__ . '/Components/HtmlEditor.php');
require_once(__DIR__ . '/Components/Popupmenu.php');
require_once(__DIR__ . '/Components/Taskmenu.php');
require_once(__DIR__ . '/Components/Toolbarmenu.php');