MDL-43883 Behat: Make Atto the default text editor and adjust behat to use it.

This commit is contained in:
Damyon Wiese 2014-02-13 15:57:44 +08:00
parent da00661d1f
commit 9f07f05a48
7 changed files with 15 additions and 228 deletions

View file

@ -577,70 +577,14 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
/**
* Ensures that all the page's editors are loaded.
*
* This method is expensive as it waits for .mceEditor CSS
* so use with caution and only where there will be editors.
*
* @deprecated since Moodle 2.7 MDL-44084 - please do not use this function any more.
* @throws ElementNotFoundException
* @throws ExpectationException
* @return void
*/
protected function ensure_editors_are_loaded() {
if (!$this->running_javascript()) {
return;
}
// If there are no editors we don't need to wait.
try {
$this->find('css', '.mceEditor', false, false, self::REDUCED_TIMEOUT);
} catch (ElementNotFoundException $e) {
return;
}
// Exception if it timesout and the element is not appearing.
$msg = 'The editors are not completely loaded';
$exception = new ExpectationException($msg, $this->getSession());
// Here we know that there are .mceEditor editors in the page and we will
// probably need to interact with them, if we use tinyMCE JS var before
// it exists it will throw an exception and we want to catch it until all
// the page's editors are ready to interact with them.
$this->spin(
function($context) {
// It may return 0 if tinyMCE is loaded but not the instances, so we just loop again.
$neditors = $context->getSession()->evaluateScript('return tinyMCE.editors.length;');
if ($neditors == 0) {
return false;
}
// It may be there but not ready.
$iframeready = $context->getSession()->evaluateScript('
var readyeditors = new Array;
for (editorid in tinyMCE.editors) {
if (tinyMCE.editors[editorid].getDoc().readyState === "complete") {
readyeditors[editorid] = editorid;
}
}
if (tinyMCE.editors.length === readyeditors.length) {
return "complete";
}
return "";
');
// Now we know that the editors are there.
if ($iframeready) {
return true;
}
// Loop again if it is not ready.
return false;
},
false,
self::EXTENDED_TIMEOUT,
$exception,
true
);
debugging('Function behat_base::ensure_editors_are_loaded() is deprecated. It is no longer required.');
return;
}
}

View file

@ -48,118 +48,14 @@ class behat_form_editor extends behat_form_textarea {
*/
public function set_value($value) {
$lastexception = null;
// We want the editor to be ready, otherwise the value can not
// be set and an exception is thrown.
for ($i = 0; $i < behat_base::EXTENDED_TIMEOUT; $i++) {
try {
// Get tinyMCE editor id if it exists.
if ($editorid = $this->get_editor_id()) {
// Set the value to the iframe and save it to the textarea.
$value = str_replace('"', '\"', $value);
$this->session->executeScript('
tinyMCE.get("'.$editorid.'").setContent("' . $value . '");
tinyMCE.get("'.$editorid.'").save();
');
} else {
// Set the value to a textarea otherwise.
parent::set_value($value);
}
return;
} catch (Exception $e) {
// Catching any kind of exception and ignoring it until times out.
$lastexception = $e;
// Waiting 0.1 seconds.
usleep(100000);
}
$editorid = $this->field->getAttribute('id');
if ($this->running_javascript()) {
$js = 'M.editor_atto.get_editable_node("'.$editorid.'").setHTML("' . $value . '").focus();';
$result = $this->session->executeScript($js);
} else {
parent::set_value($value);
}
// If it is not available we throw the last exception.
throw $lastexception;
}
/**
* Returns the field value.
*
* @return string
*/
public function get_value() {
// Can be be a string value or an exception depending whether the editor loads or not.
$lastoutcome = '';
// We want the editor to be ready to return the correct value, sometimes the
// page loads too fast and the returned value may be '' if the editor didn't
// have enough time to load completely despite having a different value.
for ($i = 0; $i < behat_base::EXTENDED_TIMEOUT; $i++) {
try {
// Get tinyMCE editor id if it exists.
if ($editorid = $this->get_editor_id()) {
// Save the current iframe value in case default value has been edited.
$this->session->executeScript('tinyMCE.get("'.$editorid.'").save();');
}
$lastoutcome = $this->field->getValue();
// We only want to wait until it times out if the value is empty.
if ($lastoutcome != '') {
return $lastoutcome;
}
} catch (Exception $e) {
// Catching any kind of exception and ignoring it until times out.
$lastoutcome = $e;
// Waiting 0.1 seconds.
usleep(100000);
}
}
// If it is not available we throw the last exception.
if (is_a($lastoutcome, 'Exception')) {
throw $lastoutcome;
}
// Return the value if there are no exceptions it will be '' at this point
return $lastoutcome;
}
/**
* Returns the tinyMCE editor id or false if it is not available.
*
* The editor availability depends on the driver running the tests; Goutte
* can not execute Javascript, also some Moodle settings disables the HTML
* editor.
*
* @return mixed The id of the editor of false if it is not available
*/
protected function get_editor_id() {
// Non-JS drivers throws exceptions when running JS.
try {
$available = $this->session->evaluateScript('return (typeof tinyMCE != "undefined")');
// Also checking that it exists a tinyMCE editor for the requested field.
$editorid = $this->field->getAttribute('id');
$available = $this->session->evaluateScript('return (typeof tinyMCE.get("'.$editorid.'") != "undefined")');
} catch (Exception $e) {
return false;
}
// No available if JS drivers returned false.
if ($available == false) {
return false;
}
return $editorid;
}
}

View file

@ -129,7 +129,7 @@ function xmldb_main_install() {
'sessiontimeout' => 7200, // must be present during roles installation
'stringfilters' => '', // These two are managed in a strange way by the filters
'filterall' => 0, // setting page, so have to be initialised here.
'texteditors' => 'tinymce,textarea',
'texteditors' => 'atto,tinymce,textarea',
);
foreach($defaults as $key => $value) {
set_config($key, $value);

View file

@ -1,49 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Atto text editor installation steps.
*
* @package editor_atto
* @copyright 2013 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Enable this text editor by default.
*
* @return bool
*/
function xmldb_editor_atto_install() {
global $CFG;
// Get the current list of editors.
$currentconfig = $CFG->texteditors;
if (is_null($currentconfig)) {
$currentconfig = '';
}
$editors = explode(',', $currentconfig);
// Insert atto in the second position.
array_splice($editors, 1, 0, array('atto'));
// Remove duplicates.
$editors = array_unique($editors);
// Set the new config.
unset_config('texteditors');
set_config('texteditors', implode(',', $editors));
return true;
}

View file

@ -9,6 +9,11 @@ Feature: Add or remove items from the TinyMCE editor toolbar
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And I log in as "admin"
And I follow "Admin User"
And I follow "Edit profile"
And I select "TinyMCE HTML editor" from "Text editor"
And I press "Update profile"
And I follow "Home"
@javascript
Scenario: Remove icons

View file

@ -99,9 +99,6 @@ class behat_forms extends behat_base {
*/
protected function expand_all_fields() {
// We ensure that all the editors are loaded and we can interact with them.
$this->ensure_editors_are_loaded();
// We already know that we waited for the DOM and the JS to be loaded, even the editor
// so, we will use the reduced timeout as it is a common task and we should save time.
try {

View file

@ -95,12 +95,6 @@ class behat_permissions extends behat_base {
try {
$advancedtoggle = $this->find_button(get_string('showadvanced', 'form'));
if ($advancedtoggle) {
// As we are interacting with a moodle form we wait for the editor to be ready
// otherwise we may have problems when setting values on it or clicking on elements
// as the position of the elements will change once the editor is loaded.
$this->ensure_editors_are_loaded();
$advancedtoggle->click();
// Wait for the page to load.