Skip to content

Commit

Permalink
added behat test to make sure we can retrieve student's answers to a …
Browse files Browse the repository at this point in the history
…file question
  • Loading branch information
martin-call-learning committed Mar 16, 2023
1 parent cedfd38 commit a21daff
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 0 deletions.
196 changes: 196 additions & 0 deletions tests/behat/behat_mod_questionnaire.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,4 +389,200 @@ private function add_data(array $data, $datatable, $mapvar = '', array $replvars
}

}

/**
* Uploads a file to the specified filemanager leaving other fields in upload form default. The paths should be relative to moodle codebase.
*
* @When /^I upload "(?P<filepath_string>(?:[^"]|\\")*)" to questionnaire filemanager$/
* @throws DriverException
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath
*/
public function i_upload_file_to_questionnaire_filemanager($filepath) {
$this->upload_file_to_filemanager_questionnaire($filepath, new TableNode(array()));
}

/**
* Try to get the filemanager node specified by the element
*
* @param string $filepickerelement
* @return \Behat\Mink\Element\NodeElement
* @throws ExpectationException
*/
protected function get_filemanager() {

// If no file picker label is mentioned take the first file picker from the page.
return $this->find(
'xpath',
'//div[contains(concat(" ", normalize-space(@class), " "), " filemanager ")]'
);
}

/**
* Uploads a file to filemanager
*
* @throws DriverException
* @throws ExpectationException Thrown by behat_base::find
* @param string $filepath Normally a path relative to $CFG->dirroot, but can be an absolute path too.
* @param string $filemanagerelement
* @param TableNode $data Data to fill in upload form
* @param false|string $overwriteaction false if we don't expect that file with the same name already exists,
* or button text in overwrite dialogue ("Overwrite", "Rename to ...", "Cancel")
*/
protected function upload_file_to_filemanager_questionnaire($filepath, TableNode $data, $overwriteaction = false) {
global $CFG;

if (!$this->has_tag('_file_upload')) {
throw new DriverException('File upload tests must have the @_file_upload tag on either the scenario or feature.');
}

$filemanagernode = $this->get_filemanager();

// Opening the select repository window and selecting the upload repository.
$this->open_add_file_window($filemanagernode, get_string('pluginname', 'repository_upload'));

// Ensure all the form is ready.
$noformexception = new ExpectationException('The upload file form is not ready', $this->getSession());
$this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" .
"[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" .
"/descendant::form",
$noformexception
);
// After this we have the elements we want to interact with.

// Form elements to interact with.
$file = $this->find_file('repo_upload_file');

// Attaching specified file to the node.
// Replace 'admin/' if it is in start of path with $CFG->admin .
if (substr($filepath, 0, 6) === 'admin/') {
$filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $CFG->admin .
DIRECTORY_SEPARATOR . substr($filepath, 6);
}
$filepath = str_replace('/', DIRECTORY_SEPARATOR, $filepath);
if (!is_readable($filepath)) {
$filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $filepath;
if (!is_readable($filepath)) {
throw new ExpectationException('The file to be uploaded does not exist.', $this->getSession());
}
}
$file->attachFile($filepath);

// Fill the form in Upload window.
$datahash = $data->getRowsHash();

// The action depends on the field type.
foreach ($datahash as $locator => $value) {

$field = behat_field_manager::get_form_field_from_label($locator, $this);

// Delegates to the field class.
$field->set_value($value);
}

// Submit the file.
$submit = $this->find_button(get_string('upload', 'repository'));
$submit->press();

// We wait for all the JS to finish as it is performing an action.
$this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);

if ($overwriteaction !== false) {
$overwritebutton = $this->find_button($overwriteaction);
$this->ensure_node_is_visible($overwritebutton);
$overwritebutton->click();

// We wait for all the JS to finish.
$this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);
}

}

/**
* Try to get the filemanager node specified by the element
*
* @param string $filepickerelement
* @return \Behat\Mink\Element\NodeElement
* @throws ExpectationException
*/
protected function get_filepicker_node($filepickerelement) {

// More info about the problem (in case there is a problem).
$exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession());

// If no file picker label is mentioned take the first file picker from the page.
if (empty($filepickerelement)) {
$filepickercontainer = $this->find(
'xpath',
"//*[@class=\"form-filemanager\"]",
$exception
);
} else {
// Gets the filemanager node specified by the locator which contains the filepicker container
// either for filepickers created by mform or by admin config.
$filepickerelement = behat_context_helper::escape($filepickerelement);
$filepickercontainer = $this->find(
'xpath',
"//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" .
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
$exception
);
}

return $filepickercontainer;
}
/**
* Opens the filepicker modal window and selects the repository.
*
* @throws ExpectationException Thrown by behat_base::find
* @param NodeElement $filemanagernode The filemanager or filepicker form element DOM node.
* @param mixed $repositoryname The repo name.
* @return void
*/
protected function open_add_file_window($filemanagernode, $repositoryname) {
$exception = new ExpectationException('No files can be added to the specified filemanager', $this->getSession());

// We should deal with single-file and multiple-file filemanagers,
// catching the exception thrown by behat_base::find() in case is not multiple
$this->execute('behat_general::i_click_on_in_the', [
'div.fp-btn-add a, input.fp-btn-choose', 'css_element',
$filemanagernode, 'NodeElement'
]);

// Wait for the default repository (if any) to load. This checks that
// the relevant div exists and that it does not include the loading image.
$this->ensure_element_exists(
"//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
"[not(descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content-loading ')])]",
'xpath_element');

// Getting the repository link and opening it.
$repoexception = new ExpectationException('The "' . $repositoryname . '" repository has not been found', $this->getSession());

// Avoid problems with both double and single quotes in the same string.
$repositoryname = behat_context_helper::escape($repositoryname);

// Here we don't need to look inside the selected element because there can only be one modal window.
$repositorylink = $this->find(
'xpath',
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-repo-area ')]" .
"//descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' fp-repo-name ')]" .
"[normalize-space(.)=$repositoryname]",
$repoexception
);

// Selecting the repo.
$this->ensure_node_is_visible($repositorylink);
if (!$repositorylink->getParent()->getParent()->hasClass('active')) {
// If the repository link is active, then the repository is already loaded.
// Clicking it while it's active causes issues, so only click it when it isn't (see MDL-51014).
$this->execute('behat_general::i_click_on', [$repositorylink, 'NodeElement']);
}
}
}
50 changes: 50 additions & 0 deletions tests/behat/file_question.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@mod @mod_questionnaire
Feature: In questionnaire, we can add a question requiring a file upload.

@javascript @_file_upload
Scenario: As a teacher, I create a questionnaire in my course with a file question and a student answers to it. Then the file has to be accessible.
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | description | course | idnumber | resume | navigate |
| questionnaire | Test questionnaire | Test questionnaire description | C1 | questionnaire0 | 1 | 1 |

When I log in as "teacher1"
And I am on "Course 1" course homepage
And I follow "Test questionnaire"
And I navigate to "Questions" in current page administration
Then I should see "Add questions"
And I add a "File" question and I fill the form with:
| Question Name | File question |
| Yes | Yes |
| Question Text | Add a file as an answer |
And I log out

Given I log in as "student1"
And I am on "Course 1" course homepage
And I follow "Test questionnaire"
And I navigate to "Answer the questions..." in current page administration
When I upload "mod/questionnaire/tests/fixtures/testfilequestion.pdf" to questionnaire filemanager
And I press "Submit questionnaire"
Then I should see "Thank you for completing this Questionnaire."
And I press "Continue"
And I should see "Your response"
And I log out

Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I follow "Test questionnaire"
When I navigate to "View All Responses" in current page administration
Then I should see "testfilequestion.pdf"
And I follow "student1"
# Todo find how to check if the pdf viewer is there.
And I log out
Binary file added tests/fixtures/testfilequestion.pdf
Binary file not shown.

0 comments on commit a21daff

Please sign in to comment.