Behat tests: input multi-line to textarea

Behat tests: input multi-line to textarea

by James Ballard -
Number of replies: 16

Hi

How can I insert multi-line response to a text-area field, for example to create a drop-down menu in the custom user profiles.

We have tried the following syntax and they don't seem to work:

  • newline "\n"
  • pystring 
  • html characters: 
 - Line Feed and 
 Carriage Return

Is there a way to do this?

Yours

James

Average of ratings: -
In reply to James Ballard

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

Hello James,

AFAIK there is no existing step in moodle which support multi-line.

What was the step definition, when you tried with pystring? Make sure this is last param in your step and you don't have to match it with any pattern


In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by David Monllaó -

Hi,

IIRC pystrings are a different data input for a step, you could write a new step definition if you want to use pystrings

In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by James Ballard -

Hi Rajesh,

I was using the same format for each and trying different options. 

Newline

And I set the field "Menu options (one per line)" to "option one/noption two/noption three"

Pystring

And I set the field "Menu options (one per line)" to
"""
option one
option two
option three
"""

HTML entities

And I set the field "Menu options (one per line)" to "option one

option two

option three"

We have defined a custom step that processes the new lines in the back-end so we can test subsequent functionality.

Yours

James

In reply to James Ballard

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

Hello James,


Steps looks fine, can you please share step definition so I can give it a try.

In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by James Ballard -

Thanks Rajesh,

I am using the core step definition for "set field to".

We haven't made modifications to this and wanted to check whether we were missing something.

Yours

James

In reply to James Ballard

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

That step will not work for pystring, you need to have a custom step

/**
* Sets the specified multi-line value to the field
*
* @Given /^I set the text field "(?P<field_string>(?:[^"]|\\")*)" with multi-line text:/
*/
public function i_set_the_text_field_with_multi_line_text($field, \Behat\Gherkin\Node\PyStringNode $value) {
$this->set_field_value($field, $value);
}

Feature file:

@test
Feature: In order to test multi-line text input
As an admin I should go to Mathjax filter and set value
@javascript
Scenario: Set MathJax configuration to check mult-line.
Given I log in as "admin"
And I navigate to "MathJax" node in "Site administration > Plugins > Filters"
And I set the text field "MathJax configuration" with multi-line text:
"""
This is first line
This is second line
"""
And pause
In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Rajesh (I address you as Behat component owner) please can we stop this irritation proliferation of different words in out Behat step definitions.

The other step is {I set the field "xxx" to value "yyy"} but here you are proposing {I set the field "xxx" with ...}

Sometimes it is {... the "xxx" "container"} and in other places it is just {... "xxx" "container"}

There are many more examples.

This inconsistency makes it impossible to write Behat feature files without having the generated documentation open beside you. It is just a pain. Please can you work on getting it standardised, at least for all new steps defined. It may be more pain that it is worth to fix the old rules.

In reply to Tim Hunt

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

Thanks for pointing that Tim,

Agreed, we should be more careful with step definition. My IDE fills that for me, so I never realised it can be pain for other not using the IDE.

Will be careful if we plan to add this in core smile

In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by Kevin Wiliarty -

I created a custom step definition similar to the one suggested above for Moodle 2.6. I'll include the details below, but so as not to bury the headline, my custom step definition works nicely in 2.6 but is not working in 2.7 or 2.8. I've tried lots of variations and get a variety of errors (which I will explain) but no success.

This is the original custom step definition that works well for Moodle 2.6. It's in a file at /filter/videojs/tests/behat/behat_filter_videojs.php

<?php

class behat_filter_videojs extends behat_base {
/**
* Sets the contents of a field with multi-line input.
*
* @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to:$/
*/
public function i_set_the_field_to_pystring($fieldlocator, Behat\Gherkin\Node\PyStringNode $value) {
$field = behat_field_manager::get_form_field_from_label($fieldlocator, $this);
$field->set_value($value->getRaw());
}
}

I invoke that step in a feature file at /filter/videojs/tests/behat/single_video.feature that looks like this. There are other scenarios than the one here, but this shows the idea:

@filter @filter_videojs
Feature: Simple HTML5 video embed
In order to embed an HTML5 video
As a user
I need to use a videojs shortcode with an mp4 and webm (or ogv) file

Background:
Given the following "courses" exist:
| fullname | shortname |
| VideoJS | videojs |
And the following "users" exist:
| username |
| tester |
And the following "course enrolments" exist:
| user | course | role |
| tester | videojs | editingteacher |
And the following "activities" exist:
| activity | course | idnumber | name | intro |
| page | videojs | videojspage | VideoJS Page | for testing |
And I log in as "admin"
And I expand "Site administration" node
And I navigate to "Manage filters" node in "Site administration>Plugins>Filters"
And I click on "On" "option" in the "Video.js" "table_row"
And I log out
And I log in as "tester"
And I follow "VideoJS"

@javascript
Scenario: Embed a single HTML5 video on a Page resource
Given I click on "VideoJS Page" "link" in the "VideoJS Page" activity
And I navigate to "Edit settings" node in "Page module administration"
And I set the field "Page content" to:
"""
Hello!
[videojs]
mp4="../../filter/videojs/tests/fixtures/activity-and-resource-controls.mp4"
webm="../../filter/videojs/tests/fixtures/activity-and-resource-controls.webm"
[/videojs]
"""
When I click on "Save and display" "button"
And I wait until the page is ready
Then ".video-js" "css_element" should exist

In Moodle 2.6 all is well, but in Moodles 2.7 and 2.8 my pystring step returns red with this message:

      unterminated string literal
Build info: version: '2.45.0', revision: '5017cb8', time: '2015-02-26 23:59:50'
System info: <some system info suppressed> os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9.5', java.version: '1.7.0_51'
Driver info: driver.version: unknown

These Moodle installations are all running in the same local environment.

I have tried using the custom step definition offered above (removing one of two spaces after the word 'field' in the doc block @Given line, and making appropriate adjustments to my feature file). In that case I get this error:

Coding error detected, it must be fixed by a programmer: The "set_field_value" method does not exist

This is understandable because my class extends behat_base rather than behat_forms. If I try to extend behat_forms I get:

Fatal error: Class 'behat_forms' not found

And if I try to include lib/tests/behat/behat_forms.php I get redundancy errors for having identical tests. 

Do you have any idea what I can do to get my pystring step to work in 2.7 and 2.8?

In reply to Kevin Wiliarty

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

Hello Kevin,


set_field_value was added in 2.6.2+ (MDL-43738), so any version lower will have problems. Also, set_field_value is protected function, so if your class is extending anything other then behat_forms then it will give coding error. Your original step should have worked as field->set_value() should work.

It seems behat_form_editor::set_value() is causing the problem. It will be great if you can debug this further:

1. Try set simple multi-line text (without tags, double quotes)

2. If above works then try with $field->set_value($value); (Text as passed don't use raw.)





In reply to Rajesh Taneja

Re: Behat tests: input multi-line to textarea

by Kevin Wiliarty -

Thanks for helping me out, Rajesh. I've done some debugging as you suggest. In particular I modified my step definition to try pystrings of increasing suspicion, like this:

And I set the field "Page content" to:
"""
Hello!
"""
And I set the field "Page content" to:
"""
Hello!
Good-bye!
"""
And I set the field "Page content" to:
"""
Hello!
[videojs]
[/videojs]
"""
And I set the field "Page content" to:
"""
Hello!
[videojs]
mp4='../../filter/videojs/tests/fixtures/activity-and-resource-controls.mp4'
webm='../../filter/videojs/tests/fixtures/activity-and-resource-controls.webm'
[/videojs]
"""
And I set the field "Page content" to:
"""
Hello!
[videojs]
mp4="../../filter/videojs/tests/fixtures/activity-and-resource-controls.mp4"
webm="../../filter/videojs/tests/fixtures/activity-and-resource-controls.webm"
[/videojs]
"""

Only the very first step succeeded. So we are okay with the triple quotation syntax and a single line, but as soon as there is a second line I get a failure. I've confirmed that I have unix line endings.

A print_r on $value returns an array of lines such as:

Behat\Gherkin\Node\PyStringNode Object
(
[lines:Behat\Gherkin\Node\PyStringNode:private] => Array
(
[0] => Hello!
[1] => Good-bye!
)

)

I get the same success / failure pattern setting the field to $value as to $value->getRaw.

In reply to Kevin Wiliarty

Re: Behat tests: input multi-line to textarea

by Kevin Wiliarty -

I see that there are some big differences between 2.6 and 2.8 with regard to behat_form_editor::set_value(). The 2.6 version is bound to TinyMCE, for instance. I'll try to troubleshoot that method specfically.

In reply to Kevin Wiliarty

Re: Behat tests: input multi-line to textarea

by Itamar Tzadok -

With $value as PyString, try $value->__toString(). smile

In reply to Itamar Tzadok

Re: Behat tests: input multi-line to textarea

by Kevin Wiliarty -

Thanks for the suggestion, Itamar. It seems to yield the same result as $value->getRaw(), but maybe I'm missing something. The definition of the __toString() method seems just to call getRaw(), and it is still the case that strings with a newline cause an 'unterminated string literal' error for me.

I have had success with a string replacement, however:

class behat_filter_videojs extends behat_base {
/**
* Sets the contents of a field with multi-line input.
*
* @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to:$/
*/
public function i_set_the_field_to_pystring($fieldlocator, Behat\Gherkin\Node\PyStringNode $value) {
$field = behat_field_manager::get_form_field_from_label($fieldlocator, $this);
$string = str_replace("\n", '\\n', $value->__toString());
$field->set_value($string);
}
}

I wonder, though, if this kind of string replacement would be better housed in the set_value() method.

For what it's worth, I also tried json_encode($value->__toString()). That prevented the JavaScript error, but mangled the string so that it was not entered correctly into the textarea.

In reply to Kevin Wiliarty

Re: Behat tests: input multi-line to textarea

by Itamar Tzadok -

Yes, the __toString is really just a magic method and a simple casting should work just as well. In your example it could be something like: (string) $value. String concatenation also works. Have you considered something like the following?

    public function i_set_the_field_to($name, PyStringNode $content) {
        return array(new Given('I set the field "'. $name. '" to "'. $content. '"'));
    }

smile

In reply to James Ballard

Re: Behat tests: input multi-line to textarea

by Rajesh Taneja -

This step is now being part of moodle core. John just worked on an issue which is including this step. MDL-5583

Average of ratings: Useful (1)