Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Steps definitions for marking guides.
19
 *
20
 * @package   gradingform_guide
21
 * @category  test
22
 * @copyright 2015 Jun Pataleta
23
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
require_once(__DIR__ . '/../../../../../../lib/behat/behat_base.php');
27
 
28
use Behat\Gherkin\Node\TableNode as TableNode,
29
    Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException,
30
    Behat\Mink\Exception\ExpectationException as ExpectationException;
31
 
32
/**
33
 * Steps definitions to help with marking guides.
34
 *
35
 * @package   gradingform_guide
36
 * @category  test
37
 * @copyright 2015 Jun Pataleta
38
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class behat_gradingform_guide extends behat_base {
41
 
42
    /**
43
     * Defines the marking guide with the provided data, following marking guide's definition grid cells.
44
     *
45
     * This method fills the marking guide of the marking guide definition
46
     * form; the provided TableNode should contain one row for
47
     * each criterion and each cell of the row should contain:
48
     * # Criterion name, a.k.a. shortname
49
     * # Description for students
50
     * # Description for markers
51
     * # Max score
52
     *
53
     * Works with both JS and non-JS.
54
     *
55
     * @When /^I define the following marking guide:$/
56
     * @throws ExpectationException
57
     * @param TableNode $guide
58
     */
59
    public function i_define_the_following_marking_guide(TableNode $guide) {
60
        $steptableinfo = '| Criterion name | Description for students | Description for markers | Maximum score |';
61
 
62
        if ($criteria = $guide->getHash()) {
63
            $addcriterionbutton = $this->find_button(get_string('addcriterion', 'gradingform_guide'));
64
 
65
            foreach ($criteria as $index => $criterion) {
66
                // Make sure the criterion array has 4 elements.
67
                if (count($criterion) != 4) {
68
                    throw new ExpectationException(
69
                        'The criterion definition should contain name, description for students and markers, and maximum points. ' .
70
                        'Please follow this format: ' . $steptableinfo,
71
                        $this->getSession()
72
                    );
73
                }
74
 
75
                // On load, there's already a criterion template ready.
76
                $shortnamevisible = false;
77
                if ($index > 0) {
78
                    // So if the index is greater than 0, we click the Add new criterion button to add a new criterion.
79
                    $addcriterionbutton->click();
80
                    $shortnamevisible = true;
81
                }
82
 
83
                $criterionroot = 'guide[criteria][NEWID' . ($index + 1) . ']';
84
 
85
                // Set the field value for the Criterion name.
86
                $this->set_guide_field_value($criterionroot . '[shortname]', $criterion['Criterion name'], $shortnamevisible);
87
 
88
                // Set the field value for the Description for students field.
89
                $this->set_guide_field_value($criterionroot . '[description]', $criterion['Description for students']);
90
 
91
                // Set the field value for the Description for markers field.
92
                $this->set_guide_field_value($criterionroot . '[descriptionmarkers]', $criterion['Description for markers']);
93
 
94
                // Set the field value for the Max score field.
95
                $this->set_guide_field_value($criterionroot . '[maxscore]', $criterion['Maximum score']);
96
            }
97
        }
98
    }
99
 
100
    /**
101
     * Defines the marking guide with the provided data, following marking guide's definition grid cells.
102
     *
103
     * This method fills the table of frequently used comments of the marking guide definition form.
104
     * The provided TableNode should contain one row for each frequently used comment.
105
     * Each row contains:
106
     * # Comment
107
     *
108
     * Works with both JS and non-JS.
109
     *
110
     * @When /^I define the following frequently used comments:$/
111
     * @throws ExpectationException
112
     * @param TableNode $commentstable
113
     */
114
    public function i_define_the_following_frequently_used_comments(TableNode $commentstable) {
115
        $steptableinfo = '| Comment |';
116
 
117
        if ($comments = $commentstable->getRows()) {
118
            $addcommentbutton = $this->find_button(get_string('addcomment', 'gradingform_guide'));
119
 
120
            foreach ($comments as $index => $comment) {
121
                // Make sure the comment array has only 1 element.
122
                if (count($comment) != 1) {
123
                    throw new ExpectationException(
124
                        'The comment cannot be empty. Please follow this format: ' . $steptableinfo,
125
                        $this->getSession()
126
                    );
127
                }
128
 
129
                // On load, there's already a comment template ready.
130
                $commentfieldvisible = false;
131
                if ($index > 0) {
132
                    // So if the index is greater than 0, we click the Add frequently used comment button to add a new criterion.
133
                    $addcommentbutton->click();
134
                    $commentfieldvisible = true;
135
                }
136
 
137
                $commentroot = 'guide[comments][NEWID' . ($index + 1) . ']';
138
 
139
                // Set the field value for the frequently used comment.
140
                $this->set_guide_field_value($commentroot . '[description]', $comment[0], $commentfieldvisible);
141
            }
142
        }
143
    }
144
 
145
    /**
146
     * Performs grading of the student by filling out the marking guide.
147
     * Set one line per criterion and for each criterion set "| Criterion name | Points | Remark |".
148
     *
149
     * @When /^I grade by filling the marking guide with:$/
150
     *
151
     * @throws ExpectationException
152
     * @param TableNode $guide
153
     * @return void
154
     */
155
    public function i_grade_by_filling_the_marking_guide_with(TableNode $guide) {
156
 
157
        $criteria = $guide->getRowsHash();
158
 
159
        $stepusage = '"I grade by filling the rubric with:" step needs you to provide a table where each row is a criterion' .
160
            ' and each criterion has 3 different values: | Criterion name | Number of points | Remark text |';
161
 
162
        // First element -> name, second -> points, third -> Remark.
163
        foreach ($criteria as $name => $criterion) {
164
 
165
            // We only expect the points and the remark, as the criterion name is $name.
166
            if (count($criterion) !== 2) {
167
                throw new ExpectationException($stepusage, $this->getSession());
168
            }
169
 
170
            // Numeric value here.
171
            $points = $criterion[0];
172
            if (!is_numeric($points)) {
173
                throw new ExpectationException($stepusage, $this->getSession());
174
            }
175
 
176
            $criterionid = 0;
177
            if ($criterionnamediv = $this->find('xpath', "//div[@class='criterionshortname'][text()='$name']")) {
178
                $criteriondivname = $criterionnamediv->getAttribute('name');
179
                // Criterion's name is of the format "advancedgrading[criteria][ID][shortname]".
180
                // So just explode the string with "][" as delimiter to extract the criterion ID.
181
                if ($nameparts = explode('][', $criteriondivname)) {
182
                    $criterionid = $nameparts[1];
183
                }
184
            }
185
 
186
            if ($criterionid) {
187
                $criterionroot = 'advancedgrading[criteria]' . '[' . $criterionid . ']';
188
 
189
                $this->execute('behat_forms::i_set_the_field_to', array($criterionroot . '[score]', $points));
190
 
191
                $this->execute('behat_forms::i_set_the_field_to', array($criterionroot . '[remark]', $criterion[1]));
192
            }
193
        }
194
    }
195
 
196
    /**
197
     * Makes a hidden marking guide field visible (if necessary) and sets a value on it.
198
     *
199
     * @param string $name The name of the field
200
     * @param string $value The value to set
201
     * @param bool $visible
202
     * @return void
203
     */
204
    protected function set_guide_field_value($name, $value, $visible = false) {
205
        // Fields are hidden by default.
206
        if ($this->running_javascript() && $visible === false) {
207
            $xpath = "//*[@name='$name']/following-sibling::*[contains(concat(' ', normalize-space(@class), ' '), ' plainvalue ')]";
208
            $textnode = $this->find('xpath', $xpath);
209
            $textnode->click();
210
        }
211
 
212
        // Set the value now.
213
        $field = $this->find_field($name);
214
        $field->setValue($value);
215
    }
216
}