mirror of
https://github.com/moodle/moodle.git
synced 2025-08-02 15:49:43 +02:00
MDL-75985 behat: Standardise HTML output when comparing editor content
This commit adds a standardise_html function and updates the matches function to compare normalised content. This allows for a wider variety of valid editor output to be handled using the standard value matching steps in Behat, thus supporting editors other than Atto better.
This commit is contained in:
parent
3bc792b9b8
commit
febd5d944c
3 changed files with 72 additions and 6 deletions
|
@ -93,7 +93,60 @@ class behat_form_editor extends behat_form_textarea {
|
|||
* @return bool The provided value matches the field value?
|
||||
*/
|
||||
public function matches($expectedvalue) {
|
||||
// A text editor may silently wrap the content in p tags (or not). Neither is an error.
|
||||
return $this->text_matches($expectedvalue) || $this->text_matches('<p>' . $expectedvalue . '</p>');
|
||||
// Fetch the actual value to save fetching it multiple times.
|
||||
$actualvalue = $this->get_value();
|
||||
|
||||
if ($this->text_matches($expectedvalue, $actualvalue)) {
|
||||
// The text is an exact match already.
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->text_matches("<p>{$expectedvalue}</p>", $actualvalue)) {
|
||||
// A text editor may silently wrap the content in p tags.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Standardise both the expected value and the actual field value.
|
||||
// We are likely dealing with HTML content, given this is an editor.
|
||||
$expectedvalue = $this->standardise_html($expectedvalue);
|
||||
$actualvalue = $this->standardise_html($actualvalue);
|
||||
|
||||
// Note: We don't need to worry about the floats here that we care about in text_matches.
|
||||
// That condition isn't relevant to the content of an editor.
|
||||
if ($expectedvalue === $actualvalue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardises the HTML content for comparison.
|
||||
*
|
||||
* @param string $html The HTML content to standardise
|
||||
* @return string The standardised HTML content
|
||||
*/
|
||||
protected function standardise_html(string $html): string {
|
||||
$document = new DOMDocument();
|
||||
$errorstate = libxml_use_internal_errors(true);
|
||||
|
||||
// Format the whitespace nicely.
|
||||
$document->preserveWhiteSpace = false;
|
||||
$document->formatOutput = true;
|
||||
|
||||
// Wrap the content in a DIV element so that it is not parsed weirdly.
|
||||
// Note: We must remove newlines too because DOMDocument does not do so, despite preserveWhiteSpace being false.
|
||||
// Unfortunately this is slightly limited in that it will also remove newlines from <pre> content and similar.
|
||||
$document->loadHTML(str_replace("\n", "", "<div>{$html}</div>"), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
$document->normalizeDocument();
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($errorstate);
|
||||
|
||||
// Save the content of the 'div' element, removing the <div> and </div> tags at the start and end.
|
||||
return trim(substr(
|
||||
$document->saveHTML($document->getElementsByTagName('div')->item(0)),
|
||||
5,
|
||||
-6
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,18 +244,21 @@ class behat_form_field implements behat_session_interface {
|
|||
* Checks if the provided text matches the field value.
|
||||
*
|
||||
* @param string $expectedvalue
|
||||
* @param string|null $actualvalue The actual value. If not specified, this will be fetched from $this->get_value().
|
||||
* @return bool
|
||||
*/
|
||||
protected function text_matches($expectedvalue) {
|
||||
protected function text_matches($expectedvalue, ?string $actualvalue = null): bool {
|
||||
$actualvalue = $actualvalue ?? $this->get_value();
|
||||
|
||||
// Non strict string comparison.
|
||||
if (trim($expectedvalue) == trim($this->get_value())) {
|
||||
if (trim($expectedvalue) == trim($actualvalue)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do one more matching attempt for floats that are valid with current decsep in use
|
||||
// (let's continue non strict comparing them as strings, but once unformatted).
|
||||
$expectedfloat = unformat_float(trim($expectedvalue), true);
|
||||
$actualfloat = unformat_float(trim($this->get_value()), true);
|
||||
$actualfloat = unformat_float(trim($actualvalue), true);
|
||||
// If they aren't null or false, then we are good to be compared (basically is_numeric()).
|
||||
$goodfloats = !is_null($expectedfloat) && ($expectedfloat !== false) &&
|
||||
!is_null($actualfloat) && ($actualfloat !== false);
|
||||
|
|
|
@ -1776,7 +1776,17 @@ EOF;
|
|||
* @param string $keys The key, or list of keys, to type
|
||||
*/
|
||||
public function i_type(string $keys): void {
|
||||
behat_base::type_keys($this->getSession(), str_split($keys));
|
||||
// Certain keys, such as the newline character, must be converted to the appropriate character code.
|
||||
// Without this, keys will behave differently depending on the browser.
|
||||
$keylist = array_map(function($key): string {
|
||||
switch ($key) {
|
||||
case '\n':
|
||||
behat_keys::ENTER;
|
||||
default:
|
||||
return $key;
|
||||
}
|
||||
}, str_split($keys));
|
||||
behat_base::type_keys($this->getSession(), $keylist);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue