itemengine-cypress-automation 1.0.32 → 1.0.36
Sign up to get free protection for your applications and to get access to all the features.
- package/cypress/e2e/ILC/ListMatching/listMatchingAdditionalSettingsAnswerNumerationAndResponseOptionPlacement.js +196 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingAdditionalSettingsBasic.js +210 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingAdditionalSettingsStemAndResponseColumnHeader.js +206 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingAlternateAnswer.js +193 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingClickAndDrop.js +644 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingEditTabScoringTypes.js +105 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsAllOrNothingScoring.js +117 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsAllOrNothingScoringWithAlternateAnswer.js +30 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsManualAndNonScoredScoring.js +49 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsPartialDifferentScoringWithAlternateTab.js +36 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsPartialDifferentScorings.js +49 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsPartialEqualWeightsScoring.js +48 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsPartialEqualWeightsScoringWithAlternateTab.js +36 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsSection.js +207 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsSetCorrectAnswersCheckboxesEditTab.js +139 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingGroupedOptionsSetCorrectAnswersCheckboxesPreviewTab.js +227 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingHeaderSection.js +95 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingQuestionInstructionsAndStemsSection.js +246 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingScoringSectionBasic.js +21 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingSetCorrectAnswerSectionBasic.js +40 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsAllOrNothingScoring.js +113 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsAllOrNothingScoringWithAlternateAnswer.js +30 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsManualAndNonScoredScoring.js +48 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsPartialDIfferentScoring.js +49 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsPartialDifferentScoringWithAlternateAnswer.js +36 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsPartialEqualScoring.js +48 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsPartialEqualScoringWithAlternateAnswer.js +35 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsSection.js +233 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsSetCorrectAnswerCheckboxesEditTab.js +113 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingStandardOptionsSetCorrectAnswerCheckboxesPreviewTab.js +185 -0
- package/cypress/e2e/ILC/ListMatching/listMatchingSwitchingCases.js +47 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAdditionalSettingsAnswerNumerationAndOptionLabel.js +295 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAdditionalSettingsBasic.js +300 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAdditionalSettingsOptionStyleDropdown.js +302 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAdditionalSettingsSetPointsPopup.js +273 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAllOrNothingScoring.js +178 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingAllOrNothingScoringWithAlternateAnswer.js +712 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingEditTabBasicSection.js +316 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingEditTabScoringSection.js +256 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingHeaderSection.js +83 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingManuallyAndNonScoredScoring.js +160 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingPartialDifferentWeightsScoring.js +191 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingPartialDifferentWeightsScoringWithAlternateAnswer.js +895 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingPartialEqualWeightsScoring.js +191 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingPartialEqualWeightsScoringWithAlternateAnswer.js +807 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingSetCorrectAnswerCheckboxes.js +208 -0
- package/cypress/e2e/ILC/ListOrdering/listOrderingSetCorrectAnswerSection.js +172 -0
- package/cypress/e2e/ILC/ListSorting/listSortingAdditionalSettings.js +820 -0
- package/cypress/e2e/ILC/ListSorting/listSortingAutoScoredScoring.js +936 -0
- package/cypress/e2e/ILC/ListSorting/listSortingClickAndDrop.js +456 -0
- package/cypress/e2e/ILC/ListSorting/listSortingEditTabBasicSection.js +440 -0
- package/cypress/e2e/ILC/ListSorting/listSortingEditTabScoringSection.js +259 -0
- package/cypress/e2e/ILC/ListSorting/listSortingHeaderSection.js +89 -0
- package/cypress/e2e/ILC/ListSorting/listSortingManuallyAndNonScoredScoring.js +171 -0
- package/cypress/e2e/ILC/ListSorting/listSortingPartialDifferentWeightsScoring.js +1150 -0
- package/cypress/e2e/ILC/ListSorting/listSortingPartialEqualWeightsScoring.js +1055 -0
- package/cypress/e2e/ILC/ListSorting/listSortingSetCorrectAnswerCheckboxes.js +263 -0
- package/cypress/e2e/ILC/ListSorting/listSortingSetCorrectAnswerSection.js +168 -0
- package/package.json +1 -1
@@ -0,0 +1,95 @@
|
|
1
|
+
import { dialogBoxBase, listMatchingPage } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
import utilities from "../../../support/helpers/utilities";
|
4
|
+
|
5
|
+
describe('Create question page - list matching: Header section and Saving question', () => {
|
6
|
+
before(() => {
|
7
|
+
cy.loginAs('admin');
|
8
|
+
});
|
9
|
+
|
10
|
+
describe('Header section contents', () => {
|
11
|
+
abortEarlySetup();
|
12
|
+
before(() => {
|
13
|
+
cy.log('Navigating to list matching question type');
|
14
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
15
|
+
cy.barsPreLoaderWait();
|
16
|
+
});
|
17
|
+
|
18
|
+
listMatchingPage.tests.verifyCreateQuestionPageQuestionTypeHeader('List matching');
|
19
|
+
});
|
20
|
+
|
21
|
+
describe('Tabs section', () => {
|
22
|
+
abortEarlySetup();
|
23
|
+
before(() => {
|
24
|
+
cy.log('Navigating to list matching question type');
|
25
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
26
|
+
cy.barsPreLoaderWait();
|
27
|
+
});
|
28
|
+
|
29
|
+
listMatchingPage.tests.verifyTabsSection();
|
30
|
+
});
|
31
|
+
|
32
|
+
describe('Cancel button', () => {
|
33
|
+
abortEarlySetup();
|
34
|
+
before(() => {
|
35
|
+
cy.log('Navigating to list matching question type');
|
36
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
37
|
+
cy.barsPreLoaderWait();
|
38
|
+
});
|
39
|
+
|
40
|
+
listMatchingPage.tests.verifyCancelButton('list matching');
|
41
|
+
});
|
42
|
+
|
43
|
+
describe('Save Question button', () => {
|
44
|
+
abortEarlySetup();
|
45
|
+
before(() => {
|
46
|
+
cy.log('Navigating to list matching question type');
|
47
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
48
|
+
cy.barsPreLoaderWait();
|
49
|
+
});
|
50
|
+
|
51
|
+
describe('Validation error messages', () => {
|
52
|
+
dialogBoxBase.tests.verifyRequiredFieldsWarningPopupOnClickingSaveButton();
|
53
|
+
|
54
|
+
it('Validation error messages should be displayed below required input fields (Question instructions, Stems input fields, Options for drag & drop input fields, Points input field, set correct answer section)', () => {
|
55
|
+
listMatchingPage.steps.verifyQuestionInstructionsErrorMessage();
|
56
|
+
listMatchingPage.steps.verifyStemFieldErrorMessage();
|
57
|
+
listMatchingPage.steps.verifyOptionFieldErrorMessage();
|
58
|
+
listMatchingPage.steps.verifyPointsFieldErrorMessage();
|
59
|
+
listMatchingPage.steps.verifySetCorrectAnswerErrorIconIsDisplayed();
|
60
|
+
listMatchingPage.steps.verifySetCorrectAnswerErrorMessage();
|
61
|
+
});
|
62
|
+
|
63
|
+
it('When the user has made no changes and switches to the preview tab and clicks on \'Save question\' button, the user should get a warning popup and on closing the warning popup, the user should be on the edit tab', () => {
|
64
|
+
listMatchingPage.steps.switchToPreviewTab();
|
65
|
+
listMatchingPage.steps.clickOnSaveQuestionButton();
|
66
|
+
utilities.verifyElementVisibilityState(dialogBoxBase.dialogBox(), 'visible');
|
67
|
+
dialogBoxBase.steps.closeWarningPopup();
|
68
|
+
listMatchingPage.steps.verifyEditTabSelectedState();
|
69
|
+
listMatchingPage.steps.verifyPreviewTabNotSelectedState();
|
70
|
+
});
|
71
|
+
|
72
|
+
it('Validation error messages should disappear when all required input fields are filled', () => {
|
73
|
+
listMatchingPage.steps.addQuestionInstructions();
|
74
|
+
listMatchingPage.steps.addInputToAllStemFields(['Stem 1', 'Stem 2', 'Stem 3']);
|
75
|
+
listMatchingPage.steps.addInputToOptionsForDragAndDropFields(['Option 1', 'Option 2', 'Option 3']);
|
76
|
+
listMatchingPage.steps.allotPoints(10);
|
77
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInSetCorrectAnswerSection('Option 1', 0);
|
78
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInSetCorrectAnswerSection('Option 2', 1);
|
79
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInSetCorrectAnswerSection('Option 3', 2);
|
80
|
+
listMatchingPage.steps.verifyErrorMessageIsNotDisplayed();
|
81
|
+
listMatchingPage.steps.verifySetCorrectAnswerErrorIconIsNotDisplayed();
|
82
|
+
});
|
83
|
+
|
84
|
+
listMatchingPage.tests.verifya11yOfCreateItemWrapperContents();
|
85
|
+
});
|
86
|
+
});
|
87
|
+
|
88
|
+
describe('Saving a question', () => {
|
89
|
+
it('When user has filled all the mandatory fields then on clicking on Save Question button the question should get saved and a snackbar with text \'Saved successfully!\' should be displayed', () => {
|
90
|
+
listMatchingPage.steps.saveAQuestionAndVerifySnackbar();
|
91
|
+
});
|
92
|
+
|
93
|
+
listMatchingPage.tests.verifySavedSuccessfullySnackbarCSSanda11y();
|
94
|
+
});
|
95
|
+
});
|
@@ -0,0 +1,246 @@
|
|
1
|
+
import { listMatchingPage } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
const css = Cypress.env('css');
|
4
|
+
|
5
|
+
const stems = ['Land pollution', 'Water pollution', 'Air pollution'];
|
6
|
+
|
7
|
+
describe('Create Item page - List Matching: Question Instructions and Stems section', () => {
|
8
|
+
before(() => {
|
9
|
+
cy.loginAs('admin');
|
10
|
+
});
|
11
|
+
|
12
|
+
describe('Question Instructions input field - Edit tab', () => {
|
13
|
+
abortEarlySetup();
|
14
|
+
before(() => {
|
15
|
+
cy.log('Navigating to List Matching question type');
|
16
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
17
|
+
cy.barsPreLoaderWait();
|
18
|
+
});
|
19
|
+
|
20
|
+
listMatchingPage.tests.verifyQuestionInstructionsInputFieldEditTab();
|
21
|
+
});
|
22
|
+
|
23
|
+
describe('Question Instructions input field - Preview tab', () => {
|
24
|
+
abortEarlySetup();
|
25
|
+
before(() => {
|
26
|
+
cy.log('Navigating to List Matching question type');
|
27
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
28
|
+
cy.barsPreLoaderWait();
|
29
|
+
});
|
30
|
+
|
31
|
+
listMatchingPage.tests.verifyQuestionInstructionsInputFieldPreviewTab();
|
32
|
+
});
|
33
|
+
|
34
|
+
describe('Stems - Edit tab stems section contents', () => {
|
35
|
+
abortEarlySetup();
|
36
|
+
before(() => {
|
37
|
+
cy.log('Navigating to List Matching question type');
|
38
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
39
|
+
cy.barsPreLoaderWait();
|
40
|
+
});
|
41
|
+
|
42
|
+
it('\'Stems\' label should be displayed', () => {
|
43
|
+
listMatchingPage.stemsLabel()
|
44
|
+
.verifyInnerText('Stems');
|
45
|
+
});
|
46
|
+
|
47
|
+
it('By default, 3 \'Stem\' input fields should be displayed with placeholder text and numeration, Drag handle and Delete option icon buttons should be displayed besides each input field', () => {
|
48
|
+
for (let index = 0; index < 3; index++) {
|
49
|
+
listMatchingPage.steps.verifyStemContents(index)
|
50
|
+
}
|
51
|
+
listMatchingPage.stemWrapper()
|
52
|
+
.eq(3)
|
53
|
+
.should('not.exist');
|
54
|
+
});
|
55
|
+
|
56
|
+
it('CSS of Stems section', { tags: 'css' }, () => {
|
57
|
+
listMatchingPage.stemsLabel()
|
58
|
+
.verifyCSS(css.color.sectionHeading, css.fontSize.normal, css.fontWeight.semibold);
|
59
|
+
listMatchingPage.stemWrapper()
|
60
|
+
.eq(0)
|
61
|
+
.within(() => {
|
62
|
+
listMatchingPage.dragHandleButton()
|
63
|
+
.verifyCSS(css.color.secondaryBtnActive, css.fontSize.normal, css.fontWeight.regular);
|
64
|
+
listMatchingPage.buttonDeleteStem()
|
65
|
+
.verifyPseudoClassBeforeProperty('color', css.color.deleteIcon);
|
66
|
+
listMatchingPage.stemInputField()
|
67
|
+
.verifyCSS(css.color.text, css.fontSize.default, css.fontWeight.regular);
|
68
|
+
listMatchingPage.optionNumeration()
|
69
|
+
.verifyCSS(css.color.labels, css.fontSize.default, css.fontWeight.semibold);
|
70
|
+
});
|
71
|
+
listMatchingPage.addStemButton()
|
72
|
+
.verifyCSS(css.color.secondaryBtnActive, css.fontSize.default, css.fontWeight.medium);
|
73
|
+
});
|
74
|
+
|
75
|
+
it('On hovering over the drag handle of the stem, \'Drag to reorder\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the drag handle', () => {
|
76
|
+
listMatchingPage.steps.verifyDragHandleTooltipForStem();
|
77
|
+
});
|
78
|
+
|
79
|
+
it('When the user hovers over the enabled \'Delete\' icon buttons then, \'Delete stem\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the \'Delete\' icon button', () => {
|
80
|
+
listMatchingPage.steps.verifyDeleteButtonTooltipForStem();
|
81
|
+
});
|
82
|
+
|
83
|
+
it('When user clicks on the \'Delete\' question stem button then the respective options input field should get deleted, option numeration should change accordingly', () => {
|
84
|
+
listMatchingPage.steps.deleteStem(0);
|
85
|
+
for (let index = 0; index < 2; index++) {
|
86
|
+
listMatchingPage.steps.verifyStemContents(index)
|
87
|
+
}
|
88
|
+
listMatchingPage.stemWrapper()
|
89
|
+
.eq(2)
|
90
|
+
.should('not.exist');
|
91
|
+
});
|
92
|
+
|
93
|
+
it('When number of stem is equal to 1, then the Delete option icon buttons should be displayed in disabled state', () => {
|
94
|
+
listMatchingPage.steps.deleteStem(0);
|
95
|
+
listMatchingPage.steps.verifyDisabledDeleteStemButton(0);
|
96
|
+
});
|
97
|
+
|
98
|
+
it('When the user hovers over the disabled \'Delete\' icon buttons then, \'Minimum one stem is required\' message should be displayed on a tooltip and the tooltip should disappear if focus is removed from the \'Delete\' icon button', () => {
|
99
|
+
listMatchingPage.steps.verifyDisabledDeleteStemButtonTooltip();
|
100
|
+
});
|
101
|
+
|
102
|
+
it('\'Add stem\' button should be present', () => {
|
103
|
+
listMatchingPage.addStemButton()
|
104
|
+
.verifyInnerText('Add stem')
|
105
|
+
.should('be.visible');
|
106
|
+
});
|
107
|
+
|
108
|
+
it('When user adds a question stem using the \'Add stem\' button then added stem should be displayed with drag handle, placeholder text, option numeration and delete button', () => {
|
109
|
+
listMatchingPage.steps.addStem()
|
110
|
+
listMatchingPage.steps.verifyStemContents(1)
|
111
|
+
});
|
112
|
+
|
113
|
+
it('When user focus in and out of any of the \'Stem\' input field without typing anything, an error message should be thrown', () => {
|
114
|
+
listMatchingPage.steps.focusInAndFocusOutOfStemInputField(1);
|
115
|
+
listMatchingPage.steps.verifyStemErrorMessageIsDisplayed(1);
|
116
|
+
});
|
117
|
+
|
118
|
+
it('CSS of error message', { tags: 'css' }, () => {
|
119
|
+
listMatchingPage.stemWrapper()
|
120
|
+
.eq(1)
|
121
|
+
.within(() => {
|
122
|
+
listMatchingPage.errorMessage()
|
123
|
+
.verifyCSS(css.color.errorText, css.fontSize.small, css.fontWeight.regular);
|
124
|
+
});
|
125
|
+
});
|
126
|
+
|
127
|
+
it('Accessibility of error message', { tags: 'a11y' }, () => {
|
128
|
+
cy.checkAccessibility(listMatchingPage.errorMessage());
|
129
|
+
});
|
130
|
+
|
131
|
+
it('When user enters text in question stem input field the \'Error: Question stem is required.\' error message should disappear', () => {
|
132
|
+
listMatchingPage.steps.addInputToStemField(1, stems[1]);
|
133
|
+
listMatchingPage.steps.verifyStemErrorMessageIsNotDisplayed(1);
|
134
|
+
});
|
135
|
+
});
|
136
|
+
|
137
|
+
describe('Stems - set correct answer section', () => {
|
138
|
+
abortEarlySetup();
|
139
|
+
before(() => {
|
140
|
+
cy.log('Navigating to List Matching question type');
|
141
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
142
|
+
cy.barsPreLoaderWait();
|
143
|
+
});
|
144
|
+
|
145
|
+
it('When user clicks on the \'Delete\' question stem button then deleted stem should not be displayed in the \'Set Correct Answer\' section table', () => {
|
146
|
+
listMatchingPage.steps.deleteStem(0);
|
147
|
+
listMatchingPage.setCorrectAnswerStemRow()
|
148
|
+
.eq(2)
|
149
|
+
.should('not.exist');
|
150
|
+
});
|
151
|
+
|
152
|
+
it('When user adds a question stem using the \'Add stem\' button then added stem should be displayed in the \'Set Correct Answer\' section table', () => {
|
153
|
+
listMatchingPage.steps.addStem();
|
154
|
+
listMatchingPage.setCorrectAnswerStemRow()
|
155
|
+
.eq(2)
|
156
|
+
.should('exist');
|
157
|
+
});
|
158
|
+
|
159
|
+
it('When user adds text to all the stem input field, the added text should be displayed in the set correct answer section section in the stem fields', () => {
|
160
|
+
listMatchingPage.steps.addInputToAllStemFields(stems);
|
161
|
+
listMatchingPage.steps.verifyAllStemTextInSetCorrectAnswerSection(stems);
|
162
|
+
});
|
163
|
+
|
164
|
+
it('When user removes text from a stem input field, the text should also be removed from the stem field in the set correct answer section', () => {
|
165
|
+
listMatchingPage.steps.clearStemInputField(0);
|
166
|
+
listMatchingPage.steps.verifyAllStemTextInSetCorrectAnswerSection(['', 'Water pollution', 'Air pollution']);
|
167
|
+
});
|
168
|
+
|
169
|
+
it('CSS of \'Set Correct Answer\' section stems', { tags: 'css' }, () => {
|
170
|
+
listMatchingPage.setCorrectAnswerStemLabel()
|
171
|
+
.verifyCSS(css.color.text, css.fontSize.default, css.fontWeight.regular);
|
172
|
+
listMatchingPage.setCorrectAnswerStemField()
|
173
|
+
.should('have.css', 'border', `1px solid ${css.color.figDefaultComponentBorder}`);
|
174
|
+
listMatchingPage.setCorrectAnswerStemResponseArea()
|
175
|
+
.should('have.css', 'border', `2px dashed ${css.color.figDefaultComponentBorder}`);
|
176
|
+
});
|
177
|
+
});
|
178
|
+
|
179
|
+
describe('Stem - Preview tab section', () => {
|
180
|
+
abortEarlySetup();
|
181
|
+
before(() => {
|
182
|
+
cy.log('Navigating to List Matching question type');
|
183
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
184
|
+
cy.barsPreLoaderWait();
|
185
|
+
cy.log('Switching to Preview tab')
|
186
|
+
listMatchingPage.steps.switchToPreviewTab();
|
187
|
+
});
|
188
|
+
|
189
|
+
it('When user deletes a question stem then the deleted stem should not be displayed in the \'Preview\' tab table', () => {
|
190
|
+
cy.log('Switching to Edit tab')
|
191
|
+
listMatchingPage.steps.switchToEditTab();
|
192
|
+
listMatchingPage.steps.deleteStem(0);
|
193
|
+
cy.log('Switching to Preview tab')
|
194
|
+
listMatchingPage.steps.switchToPreviewTab();
|
195
|
+
listMatchingPage.previewTabStemRow()
|
196
|
+
.eq(2)
|
197
|
+
.should('not.exist');
|
198
|
+
});
|
199
|
+
|
200
|
+
it('When user adds a question stem using the \'Add stem\' button then added stem should be displayed in the \'Preview\' tab table', () => {
|
201
|
+
cy.log('Switching to Edit tab')
|
202
|
+
listMatchingPage.steps.switchToEditTab();
|
203
|
+
listMatchingPage.steps.addStem();
|
204
|
+
cy.log('Switching to Preview tab')
|
205
|
+
listMatchingPage.steps.switchToPreviewTab();
|
206
|
+
listMatchingPage.previewTabStemRow()
|
207
|
+
.eq(2)
|
208
|
+
.should('exist');
|
209
|
+
});
|
210
|
+
|
211
|
+
it('When user adds text to all the question stem input field, the added text should be displayed in the Preview tab table under the Question stem column', () => {
|
212
|
+
cy.log('Switching to Edit tab')
|
213
|
+
listMatchingPage.steps.switchToEditTab();
|
214
|
+
listMatchingPage.steps.addInputToAllStemFields(stems);
|
215
|
+
cy.log('Switching to Preview tab')
|
216
|
+
listMatchingPage.steps.switchToPreviewTab();
|
217
|
+
listMatchingPage.steps.verifyAllStemTextInPreviewTab(stems);
|
218
|
+
});
|
219
|
+
|
220
|
+
it('When user removes text from a stem input field, the text should also be removed from the stem field in the preview tab', () => {
|
221
|
+
cy.log('Switching to Edit tab')
|
222
|
+
listMatchingPage.steps.switchToEditTab();
|
223
|
+
listMatchingPage.stemInputField()
|
224
|
+
.eq(0)
|
225
|
+
.clear();
|
226
|
+
cy.log('Switching to Preview tab')
|
227
|
+
listMatchingPage.steps.switchToPreviewTab();
|
228
|
+
listMatchingPage.previewTabStemLabel()
|
229
|
+
.eq(0)
|
230
|
+
.verifyInnerText('');
|
231
|
+
});
|
232
|
+
|
233
|
+
it('CSS of added stems in \'Preview\' tab table', { tags: 'css' }, () => {
|
234
|
+
listMatchingPage.previewTabStemLabel()
|
235
|
+
.verifyCSS(css.color.text, css.fontSize.default, css.fontWeight.regular);
|
236
|
+
listMatchingPage.previewTabStemField()
|
237
|
+
.should('have.css', 'border', `1px solid ${css.color.figDefaultComponentBorder}`);
|
238
|
+
listMatchingPage.previewTabStemResponseArea()
|
239
|
+
.should('have.css', 'border', `2px dashed ${css.color.figDefaultComponentBorder}`);
|
240
|
+
});
|
241
|
+
|
242
|
+
it('Accessibility of \'Preview\' tab stem fields', { tags: 'a11y' }, () => {
|
243
|
+
cy.checkAccessibility(listMatchingPage.previewTabStemLabel().parents('[class*="ClozeWithDragAndDropstyles__QuestionItemContainer"]'));
|
244
|
+
});
|
245
|
+
});
|
246
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { listMatchingPage } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
|
4
|
+
describe('Create Item page - List matching: Scoring Section basic: Labels, dropdown, scoring radio buttons', () => {
|
5
|
+
before(() => {
|
6
|
+
cy.loginAs('admin');
|
7
|
+
});
|
8
|
+
|
9
|
+
describe('Scoring Section contents', () => {
|
10
|
+
abortEarlySetup();
|
11
|
+
before(() => {
|
12
|
+
cy.log('Navigate to list matching question type');
|
13
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
14
|
+
cy.barsPreLoaderWait();
|
15
|
+
});
|
16
|
+
|
17
|
+
listMatchingPage.tests.verifyScoringTypeLabelAndDropdown('autoScored');
|
18
|
+
|
19
|
+
listMatchingPage.tests.verifyAutoScoredScoringTypeSectionWithCSSAnda11y();
|
20
|
+
});
|
21
|
+
});
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { listMatchingPage } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
const css = Cypress.env('css');
|
4
|
+
|
5
|
+
describe('Create Item page - List Matching: Set correct answer section, correct tab', () => {
|
6
|
+
before(() => {
|
7
|
+
cy.loginAs('admin');
|
8
|
+
});
|
9
|
+
|
10
|
+
describe('Set correct answer section', () => {
|
11
|
+
abortEarlySetup();
|
12
|
+
before(() => {
|
13
|
+
cy.log('Navigating to List Matching question type');
|
14
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
15
|
+
});
|
16
|
+
|
17
|
+
listMatchingPage.tests.verifyAutoScoredSetCorrectAnswerHeaderSectionContents('list matching')
|
18
|
+
|
19
|
+
it('CSS of correct response conditions section', { tags: 'css' }, () => {
|
20
|
+
const labels = [listMatchingPage.randomizeOptionsLabel, listMatchingPage.reuseOptionsLabel, listMatchingPage.hideDragHandleLabel]
|
21
|
+
const uncheckedCheckboxes = [listMatchingPage.randomizeOptionsCheckbox, listMatchingPage.reuseOptionsCheckbox, listMatchingPage.hideDragHandleCheckbox]
|
22
|
+
labels.forEach((checkinglabel) => {
|
23
|
+
checkinglabel()
|
24
|
+
.verifyCSS(css.color.labelText, css.fontSize.normal, css.fontWeight.regular);
|
25
|
+
});
|
26
|
+
uncheckedCheckboxes.forEach((uncheckedCheckbox) => {
|
27
|
+
uncheckedCheckbox()
|
28
|
+
.parent()
|
29
|
+
.find('svg')
|
30
|
+
.should('have.css', 'fill', css.color.uncheckedCheckbox);
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
listMatchingPage.tests.verifyDefaultStateOfRandomizeOptionsCheckboxAndLabel();
|
35
|
+
|
36
|
+
listMatchingPage.tests.verifyDefaultStateOfReuseOptionsCheckboxAndLabel();
|
37
|
+
|
38
|
+
listMatchingPage.tests.verifyDefaultStateOfHideDragHandleCheckboxAndLabel();
|
39
|
+
});
|
40
|
+
});
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import { listMatchingPage, listMatchingScoring } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
|
4
|
+
describe('Create Item page - List Matching - standard options layout - All or nothing scoring', () => {
|
5
|
+
before(() => {
|
6
|
+
cy.loginAs('admin');
|
7
|
+
});
|
8
|
+
|
9
|
+
describe('Show correct answer', () => {
|
10
|
+
abortEarlySetup();
|
11
|
+
before(() => {
|
12
|
+
cy.log('Navigate to list matching question type and fill the option input fields in standard options layout');
|
13
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
14
|
+
cy.barsPreLoaderWait();
|
15
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
16
|
+
listMatchingPage.steps.switchToPreviewTab();
|
17
|
+
});
|
18
|
+
|
19
|
+
listMatchingPage.tests.verifyShowCorrectAnswerAndPointsInPreviewTabWhenNoCorrectAnswerIsSet();
|
20
|
+
|
21
|
+
listMatchingScoring.tests.verifyShowCorrectAnswerBasicFunctionality();
|
22
|
+
});
|
23
|
+
|
24
|
+
describe('Question Preview: AutoScored - All or Nothing - standard options layout', () => {
|
25
|
+
abortEarlySetup();
|
26
|
+
before(() => {
|
27
|
+
cy.log('Navigate to List matching question type, fill the necessary details and points and switch to preview tab');
|
28
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
29
|
+
cy.barsPreLoaderWait();
|
30
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
31
|
+
listMatchingPage.steps.allotPoints(20);
|
32
|
+
listMatchingPage.steps.setCorrectAnswersForScoringWithoutAlternateTab();
|
33
|
+
listMatchingPage.steps.expandAdditonalSettings();
|
34
|
+
listMatchingPage.steps.checkAllowStudentsToCheckAnswerCheckbox();
|
35
|
+
listMatchingPage.steps.switchToPreviewTab();
|
36
|
+
});
|
37
|
+
|
38
|
+
listMatchingScoring.tests.verifyAutoScoredAllOrNothingScoring();
|
39
|
+
|
40
|
+
listMatchingScoring.tests.verifyMinimumScoreAwardedIfAttemptedForIncorrectAnswer('20');
|
41
|
+
});
|
42
|
+
|
43
|
+
describe('Question Preview: AutoScored - All or Nothing standard options layout with identical response options', () => {
|
44
|
+
abortEarlySetup();
|
45
|
+
before(() => {
|
46
|
+
cy.log('Navigate to List Matching question type, fill the necessary details and points and switch to preview tab');
|
47
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
48
|
+
cy.barsPreLoaderWait();
|
49
|
+
listMatchingPage.steps.deleteStem(2);
|
50
|
+
listMatchingPage.steps.addInputToAllStemFields(['Stem 1', 'Stem 2']);
|
51
|
+
listMatchingPage.steps.addInputToOptionsForDragAndDropFields(['Identical correct answer for stem 1', 'Correct answer for stem 2', 'Identical correct answer for stem 1']);
|
52
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInSetCorrectAnswerSection('Identical correct answer for stem 1', 0);
|
53
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInSetCorrectAnswerSection('Correct answer for stem 2', 1);
|
54
|
+
listMatchingPage.steps.allotPoints(20);
|
55
|
+
listMatchingPage.steps.expandAdditonalSettings();
|
56
|
+
listMatchingPage.steps.checkAllowStudentsToCheckAnswerCheckbox();
|
57
|
+
listMatchingPage.steps.switchToPreviewTab();
|
58
|
+
});
|
59
|
+
|
60
|
+
it('Case: When user has identical options to give as input', () => {
|
61
|
+
cy.log('Both the identical options should be visible in the response options section and when user clicks on \'Show correct answer\' checkbox only one of the identical options should be displayed in the correct answer container as the correct answer');
|
62
|
+
listMatchingPage.steps.verifyOptionsInPreviewTab(['Identical correct answer for stem 1', 'Correct answer for stem 2', 'Identical correct answer for stem 1']);
|
63
|
+
listMatchingPage.steps.checkShowCorrectAnswerCheckbox();
|
64
|
+
listMatchingPage.steps.verifyCorrectAnswerStemOptionsInCorrectAnswerContainerAndCount(['Identical correct answer for stem 1', 'Correct answer for stem 2'], ['1', '2']);
|
65
|
+
|
66
|
+
cy.log('Post-step: Unchecking show correct answer checkbox');
|
67
|
+
listMatchingPage.steps.uncheckShowCorrectAnswerCheckbox();
|
68
|
+
|
69
|
+
cy.log('When the user gives the correct answer as input and user selects the show correct answer checkbox, green check-mark icon should be displayed besides both the responses, correct answer container should not be displayed and user should be awarded with full points');
|
70
|
+
|
71
|
+
cy.log('Answering the stem 1 with the correct identical option');
|
72
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInPreviewTab('Identical correct answer for stem 1', 0);
|
73
|
+
|
74
|
+
cy.log('Answering the response 2 with the correct option');
|
75
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInPreviewTab('Correct answer for stem 2', 1);
|
76
|
+
listMatchingPage.steps.checkShowCorrectAnswerCheckbox();
|
77
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(0);
|
78
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(1);
|
79
|
+
listMatchingPage.steps.verifyPreviewTabCorrectAnswerContainerNotExist();
|
80
|
+
listMatchingPage.previewScoreText()
|
81
|
+
.verifyInnerText('20/20');
|
82
|
+
|
83
|
+
cy.log('Post-step: Unchecking show correct answer checkbox');
|
84
|
+
listMatchingPage.steps.uncheckShowCorrectAnswerCheckbox();
|
85
|
+
|
86
|
+
cy.log('When user clicks on \'Check answer\' button, then green check-mark icon should be displayed besides responses and correct answer container should not be displayed');
|
87
|
+
listMatchingPage.steps.checkAnswer();
|
88
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(0);
|
89
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(1);
|
90
|
+
listMatchingPage.steps.verifyPreviewTabCorrectAnswerContainerNotExist();
|
91
|
+
|
92
|
+
cy.log('When the user gives correct input to the response but with a different identical option and user selects the show correct answer checkbox, then red cross-mark icon should be displayed besides the identical response, correct answer container be displayed with the correct answer and user should be awarded with zero points');
|
93
|
+
|
94
|
+
cy.log('Answering the response 1 with a different correct identical option');
|
95
|
+
listMatchingPage.steps.clickAndDropOptionInStemResponseAreaInPreviewTab('Identical correct answer for stem 1', 0);
|
96
|
+
listMatchingPage.steps.checkShowCorrectAnswerCheckbox();
|
97
|
+
listMatchingPage.steps.verifyIncorrectOptionCrossmarkIcon(0);
|
98
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(1);
|
99
|
+
listMatchingPage.previewScoreText()
|
100
|
+
.verifyInnerText('0/20');
|
101
|
+
listMatchingPage.steps.verifyCorrectAnswerStemOptionsInCorrectAnswerContainerAndCount(['Identical correct answer for stem 1'], ['1']);
|
102
|
+
|
103
|
+
cy.log('Post-step: Unchecking show correct answer checkbox');
|
104
|
+
listMatchingPage.steps.uncheckShowCorrectAnswerCheckbox();
|
105
|
+
|
106
|
+
cy.log('When user clicks on \'Check answer\' button, then red cross-mark icon should be displayed besides the identical response and correct answer container should not be displayed')
|
107
|
+
listMatchingPage.steps.checkAnswer()
|
108
|
+
listMatchingPage.steps.verifyIncorrectOptionCrossmarkIcon(0);
|
109
|
+
listMatchingPage.steps.verifyCorrectOptionCheckmarkIcon(1);
|
110
|
+
listMatchingPage.steps.verifyPreviewTabCorrectAnswerContainerNotExist();
|
111
|
+
});
|
112
|
+
});
|
113
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { listMatchingPage, listMatchingScoring } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
|
4
|
+
describe('Create Item page - List Matching - standard options layout - All or nothing scoring with alternate answer', () => {
|
5
|
+
before(() => {
|
6
|
+
cy.loginAs('admin');
|
7
|
+
});
|
8
|
+
|
9
|
+
describe('Question Preview: AutoScored - All or Nothing standard options layout with alternate answer', () => {
|
10
|
+
abortEarlySetup();
|
11
|
+
before(() => {
|
12
|
+
cy.log('Navigate to List Matching question type, adding correct answer responses and alternate answer responses for autoscored - all or nothing scoring, adding points and switch to preview tab');
|
13
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
14
|
+
cy.barsPreLoaderWait();
|
15
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithAlternateTab();
|
16
|
+
listMatchingPage.steps.allotPoints(7);
|
17
|
+
listMatchingPage.steps.setCorrectAnswersForCorrectTab();
|
18
|
+
listMatchingPage.steps.clickOnAddAlternateAnswerButton();
|
19
|
+
listMatchingPage.steps.allotPoints(3);
|
20
|
+
listMatchingPage.steps.setCorrectAnswersForAlternateTab();
|
21
|
+
listMatchingPage.steps.expandAdditonalSettings();
|
22
|
+
listMatchingPage.steps.checkAllowStudentsToCheckAnswerCheckbox();
|
23
|
+
listMatchingPage.steps.switchToPreviewTab();
|
24
|
+
});
|
25
|
+
|
26
|
+
listMatchingScoring.tests.verifyAutoScoredAllOrNothingScoringWithAlternateAnswer();
|
27
|
+
|
28
|
+
listMatchingScoring.tests.verifyMinimumScoreAwardedIfAttemptedForIncorrectAnswer('7');
|
29
|
+
});
|
30
|
+
});
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { listMatchingPage, listMatchingScoring } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
const css = Cypress.env('css');
|
4
|
+
|
5
|
+
describe('Create Item page - List Matching - standard options layout - Manually scored', () => {
|
6
|
+
before(() => {
|
7
|
+
cy.loginAs('admin');
|
8
|
+
});
|
9
|
+
|
10
|
+
describe('Question Preview: Manually scored standard options layout', () => {
|
11
|
+
abortEarlySetup();
|
12
|
+
before(() => {
|
13
|
+
cy.log('Navigate to question, add input to stems and options, select manually scored scoring type and switch to preview tab');
|
14
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
15
|
+
cy.barsPreLoaderWait();
|
16
|
+
listMatchingPage.steps.addQuestionInstructions();
|
17
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
18
|
+
listMatchingPage.steps.selectAScoringTypeFromScoringTypeDropdown('Manually scored');
|
19
|
+
listMatchingPage.steps.switchToPreviewTab();
|
20
|
+
});
|
21
|
+
|
22
|
+
it('When the user switches to the Preview tab, the question instruction, the question stems and options', () => {
|
23
|
+
listMatchingPage.steps.verifyQuestionInstructionsText();
|
24
|
+
listMatchingPage.steps.verifyAllStemTextInPreviewTab(['Stem 1', 'Stem 2']);
|
25
|
+
listMatchingPage.steps.verifyOptionsInPreviewTab(['Correct answer for stem 1', 'Correct answer for stem 2', 'Incorrect answer 1', 'Incorrect answer 2']);
|
26
|
+
});
|
27
|
+
|
28
|
+
listMatchingPage.tests.verifyShowCorrectAnswerAndPointsNotDisplayedInPreviewTab();
|
29
|
+
});
|
30
|
+
|
31
|
+
describe('Question Preview: Non scored standard options layout', () => {
|
32
|
+
abortEarlySetup();
|
33
|
+
before(() => {
|
34
|
+
cy.log('Navigate to question, add input to stems and options, select manually scored scoring type and switch to preview tab');
|
35
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
36
|
+
cy.barsPreLoaderWait();
|
37
|
+
listMatchingPage.steps.addQuestionInstructions();
|
38
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
39
|
+
listMatchingPage.steps.setCorrectAnswersForScoringWithoutAlternateTab();
|
40
|
+
listMatchingPage.steps.expandAdditonalSettings();
|
41
|
+
listMatchingPage.steps.checkAllowStudentsToCheckAnswerCheckbox();
|
42
|
+
listMatchingPage.steps.selectAScoringTypeFromScoringTypeDropdown('Non scored');
|
43
|
+
listMatchingPage.steps.switchToPreviewTab();
|
44
|
+
});
|
45
|
+
|
46
|
+
listMatchingScoring.tests.verifyNonScoredScoring();
|
47
|
+
});
|
48
|
+
});
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { listMatchingPage, listMatchingScoring } from "../../../pages";
|
2
|
+
import abortEarlySetup from "../../../support/helpers/abortEarly";
|
3
|
+
|
4
|
+
describe('Create Item page - List Matching - standard options layout - Partial different weights scoring', () => {
|
5
|
+
before(() => {
|
6
|
+
cy.loginAs('admin');
|
7
|
+
});
|
8
|
+
|
9
|
+
describe('Question Preview: AutoScored - Partial different weights standard options layout', () => {
|
10
|
+
abortEarlySetup();
|
11
|
+
before(() => {
|
12
|
+
cy.log('Navigate to question, add input to stems and options, set correct answers, switch to partial different weights scoring, allocate points, allow students to check answer, switch to preview tab');
|
13
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
14
|
+
cy.barsPreLoaderWait();
|
15
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
16
|
+
listMatchingPage.steps.selectPartialDifferentWeightsCheckbox()
|
17
|
+
listMatchingPage.steps.setCorrectAnswersForScoringWithoutAlternateTab();
|
18
|
+
listMatchingPage.steps.addPartialDifferentWeightsPoints([5.4, 4.6]);
|
19
|
+
listMatchingPage.steps.uncheckRoundDownScoreCheckbox();
|
20
|
+
listMatchingPage.steps.expandAdditonalSettings();
|
21
|
+
listMatchingPage.steps.checkAllowStudentsToCheckAnswerCheckbox();
|
22
|
+
listMatchingPage.steps.switchToPreviewTab();
|
23
|
+
});
|
24
|
+
|
25
|
+
listMatchingScoring.tests.verifyAutoScoredPartialDifferentWeightsScoring();
|
26
|
+
|
27
|
+
listMatchingScoring.tests.verifyMinimumScoreAwardedIfAttemptedForIncorrectAnswer('10');
|
28
|
+
|
29
|
+
listMatchingScoring.tests.verifyPenaltyPointsAwardedForIncorrectAnswer('2.6', '10');
|
30
|
+
|
31
|
+
listMatchingScoring.tests.verifyPointsAwardedForIncorrectAnswerWhenMinimumScoreAwardedAndPenaltyPointsAreDefined('2.6', '10');
|
32
|
+
});
|
33
|
+
|
34
|
+
describe('Question Preview: AutoScored - Partial different weights standard options layout - Round down score', () => {
|
35
|
+
abortEarlySetup();
|
36
|
+
before(() => {
|
37
|
+
cy.log('Navigate to question, add input to stems and options, set correct answers and allocate points, switch to partial different weights scoring, allow students to check answer, switch to preview tab');
|
38
|
+
listMatchingPage.steps.navigateToCreateQuestion('list matching');
|
39
|
+
cy.barsPreLoaderWait();
|
40
|
+
listMatchingPage.steps.setQuestionStemsAndOptionsForScoringWithoutAlternateTab();
|
41
|
+
listMatchingPage.steps.setCorrectAnswersForScoringWithoutAlternateTab();
|
42
|
+
listMatchingPage.steps.selectPartialDifferentWeightsCheckbox();
|
43
|
+
listMatchingPage.steps.addPartialDifferentWeightsPoints([4.1, 3.3]);
|
44
|
+
listMatchingPage.steps.switchToPreviewTab();
|
45
|
+
});
|
46
|
+
|
47
|
+
listMatchingScoring.tests.verifyAutoScoredPartialDifferentWeightsRoundDownScore();
|
48
|
+
});
|
49
|
+
});
|