blob: 105cf43b1fdb4139a7f22f7d328c68c7bedfaecc [file] [log] [blame]
Philipp Schrader175a93c2023-02-19 13:13:40 -08001/// <reference types="cypress" />
2
3function disableAlerts() {
4 cy.get('#block_alerts').check({force: true}).should('be.checked');
5}
6
7function switchToTab(tabName) {
8 cy.contains('.nav-link', tabName).click();
9}
10
11function headerShouldBe(text) {
12 cy.get('.header').should('have.text', text);
13}
14
15function clickButton(buttonName) {
16 cy.contains('button', buttonName).click();
17}
18
19function setInputTo(fieldSelector, value) {
20 cy.get(fieldSelector).type('{selectAll}' + value);
21}
22
23// Moves the nth slider left or right. A positive "adjustBy" value moves the
24// slider to the right. A negative value moves the slider to the left.
25//
26// negative/left <--- 0 ---> positive/right
27function adjustNthSliderBy(n, adjustBy) {
28 let element = cy.get('input[type=range]').eq(n);
29 element.scrollIntoView();
30 element.invoke('val').then((currentValue) => {
31 // We need to query for the slider here again because `invoke('val')` above
32 // somehow invalidates further calls to `val`.
33 cy.get('input[type=range]')
34 .eq(n)
35 .invoke('val', currentValue + adjustBy)
36 .trigger('change');
37 });
38}
39
40// Asserts that the field on the "Submit and Review" screen has a specific
41// value.
42function expectReviewFieldToBe(fieldName, expectedValue) {
43 expectNthReviewFieldToBe(fieldName, 0, expectedValue);
44}
45
46// Asserts that the n'th instance of a field on the "Submit and Review"
47// screen has a specific value.
48function expectNthReviewFieldToBe(fieldName, n, expectedValue) {
49 getNthReviewField(fieldName, n).should(
50 'have.text',
51 `${fieldName}: ${expectedValue}`
52 );
53}
54
55function getNthReviewField(fieldName, n) {
56 let element = cy.get('li').filter(`:contains("${fieldName}: ")`).eq(n);
57 element.scrollIntoView();
58 return element;
59}
60
61before(() => {
62 cy.visit('/');
63 disableAlerts();
64 cy.title().should('eq', 'FRC971 Scouting Application');
Philipp Schrader175a93c2023-02-19 13:13:40 -080065});
66
67beforeEach(() => {
68 cy.visit('/');
69 disableAlerts();
70});
71
72describe('Scouting app tests', () => {
73 it('should: show matches in chronological order.', () => {
74 headerShouldBe('Matches');
75 cy.get('.badge').eq(0).contains('Quals Match 1');
76 cy.get('.badge').eq(1).contains('Quals Match 2');
77 cy.get('.badge').eq(2).contains('Quals Match 3');
78 cy.get('.badge').eq(9).contains('Quals Match 10');
79 cy.get('.badge').eq(72).contains('Quarter Final 1 Match 1');
80 cy.get('.badge').eq(73).contains('Quarter Final 2 Match 1');
81 cy.get('.badge').eq(74).contains('Quarter Final 3 Match 1');
82 cy.get('.badge').eq(75).contains('Quarter Final 4 Match 1');
83 cy.get('.badge').eq(76).contains('Quarter Final 1 Match 2');
84 cy.get('.badge').eq(82).contains('Semi Final 1 Match 1');
85 cy.get('.badge').eq(83).contains('Semi Final 2 Match 1');
86 cy.get('.badge').eq(84).contains('Semi Final 1 Match 2');
87 cy.get('.badge').eq(85).contains('Semi Final 2 Match 2');
88 cy.get('.badge').eq(89).contains('Final 1 Match 3');
89 });
90
91 it('should: prefill the match information.', () => {
92 headerShouldBe('Matches');
93
94 // On the 87th row of matches (index 86) click on the second team
95 // (index 1) which resolves to team 5254 in semi final 2 match 3.
96 cy.get('button.match-item')
97 .eq(86 * 6 + 1)
98 .click();
99
100 headerShouldBe('Team Selection');
101 cy.get('#match_number').should('have.value', '3');
102 cy.get('#team_number').should('have.value', '5254');
103 cy.get('#set_number').should('have.value', '2');
104 cy.get('#comp_level').should('have.value', '3: sf');
105 });
106
Filip Kujawa0ef334c2023-02-20 19:42:45 -0800107 //TODO(FILIP): Rewrite tests for the new scouting interface.
108 /*
Philipp Schrader175a93c2023-02-19 13:13:40 -0800109 it('should: error on unknown match.', () => {
110 switchToTab('Data Entry');
111 headerShouldBe('Team Selection');
112
113 // Pick a match that doesn't exist in the 2016nytr match list.
114 setInputTo('#match_number', '3');
115 setInputTo('#team_number', '971');
116
117 // Click Next until we get to the submit screen.
118 for (let i = 0; i < 5; i++) {
119 clickButton('Next');
120 }
121 headerShouldBe('Review and Submit');
122
123 // Attempt to submit and validate the error.
124 clickButton('Submit');
125 cy.get('.error_message').contains(
126 'Failed to find team 971 in match 3 in the schedule.'
127 );
128 });
129
130 // Make sure that each page on the Entry tab has both "Next" and "Back"
131 // buttons. The only screens exempted from this are the first page and the
132 // last page.
133 it('should: have forwards and backwards buttons.', () => {
134 switchToTab('Data Entry');
135
136 const expectedOrder = [
137 'Team Selection',
138 'Auto',
139 'TeleOp',
140 'Climb',
141 'Other',
142 'Review and Submit',
143 ];
144
145 // Go forward through the screens.
146 for (let i = 0; i < expectedOrder.length; i++) {
147 headerShouldBe(expectedOrder[i]);
148 if (i != expectedOrder.length - 1) {
149 clickButton('Next');
150 }
151 }
152
153 // Go backwards through the screens.
154 for (let i = 0; i < expectedOrder.length; i++) {
155 headerShouldBe(expectedOrder[expectedOrder.length - i - 1]);
156 if (i != expectedOrder.length - 1) {
157 clickButton('Back');
158 }
159 }
160 });
Filip Kujawa0ef334c2023-02-20 19:42:45 -0800161
Philipp Schrader175a93c2023-02-19 13:13:40 -0800162
163 it('should: review and submit correct data.', () => {
164 switchToTab('Data Entry');
165
166 // Submit scouting data for a random team that attended 2016nytr.
167 headerShouldBe('Team Selection');
168 setInputTo('#match_number', '2');
169 setInputTo('#team_number', '5254');
170 setInputTo('#set_number', '42');
171 cy.get('#comp_level').select('Semi Finals');
172 clickButton('Next');
173
174 headerShouldBe('Auto');
175 cy.get('#quadrant3').check();
176 clickButton('Next');
177
178 headerShouldBe('TeleOp');
179 clickButton('Next');
180
181 headerShouldBe('Climb');
182 cy.get('#high').check();
183 clickButton('Next');
184
185 headerShouldBe('Other');
186 adjustNthSliderBy(0, 3);
187 adjustNthSliderBy(1, 1);
188 cy.get('#no_show').check();
189 cy.get('#mechanically_broke').check();
190 setInputTo('#comment', 'A very useful comment here.');
191 clickButton('Next');
192
193 headerShouldBe('Review and Submit');
194 cy.get('.error_message').should('have.text', '');
195
196 // Validate Team Selection.
197 expectReviewFieldToBe('Match number', '2');
198 expectReviewFieldToBe('Team number', '5254');
199 expectReviewFieldToBe('SetNumber', '42');
200 expectReviewFieldToBe('Comp Level', 'Semi Finals');
201
202 // Validate Auto.
203 expectNthReviewFieldToBe('Upper Shots Made', 0, '0');
204 expectNthReviewFieldToBe('Lower Shots Made', 0, '0');
205 expectNthReviewFieldToBe('Missed Shots', 0, '0');
206 expectReviewFieldToBe('Quadrant', '3');
207
208 // Validate TeleOp.
209 expectNthReviewFieldToBe('Upper Shots Made', 1, '0');
210 expectNthReviewFieldToBe('Lower Shots Made', 1, '0');
211 expectNthReviewFieldToBe('Missed Shots', 1, '0');
212
213 // Validate Climb.
214 expectReviewFieldToBe('Climb Level', 'High');
215
216 // Validate Other.
217 expectReviewFieldToBe('Defense Played On Rating', '3');
218 expectReviewFieldToBe('Defense Played Rating', '1');
219 expectReviewFieldToBe('No show', 'true');
220 expectReviewFieldToBe('Never moved', 'false');
221 expectReviewFieldToBe('Battery died', 'false');
222 expectReviewFieldToBe('Broke (mechanically)', 'true');
223 expectReviewFieldToBe('Comments', 'A very useful comment here.');
224
225 clickButton('Submit');
226 headerShouldBe('Success');
227 });
228
Filip Kujawa0ef334c2023-02-20 19:42:45 -0800229 */
Philipp Schrader175a93c2023-02-19 13:13:40 -0800230
231 it('should: submit note scouting for multiple teams', () => {
232 // Navigate to Notes Page.
233 switchToTab('Notes');
234 headerShouldBe('Notes');
235
236 // Add first team.
237 setInputTo('#team_number_notes', '1234');
238 clickButton('Select');
239
240 // Add note and select keyword for first team.
241 cy.get('#team-key-1').should('have.text', '1234');
242 setInputTo('#text-input-1', 'Good Driving');
243 cy.get('#good_driving_0').click();
244
245 // Navigate to add team selection and add another team.
246 clickButton('Add team');
247 setInputTo('#team_number_notes', '1235');
248 clickButton('Select');
249
250 // Add note and select keyword for second team.
251 cy.get('#team-key-2').should('have.text', '1235');
252 setInputTo('#text-input-2', 'Bad Driving');
253 cy.get('#bad_driving_1').click();
254
255 // Submit Notes.
256 clickButton('Submit');
257 cy.get('#team_number_label').should('have.text', ' Team Number ');
258 });
259
260 it('should: switch note text boxes with keyboard shortcuts', () => {
261 // Navigate to Notes Page.
262 switchToTab('Notes');
263 headerShouldBe('Notes');
264
265 // Add first team.
266 setInputTo('#team_number_notes', '1234');
267 clickButton('Select');
268
269 // Add second team.
270 clickButton('Add team');
271 setInputTo('#team_number_notes', '1235');
272 clickButton('Select');
273
274 // Add third team.
275 clickButton('Add team');
276 setInputTo('#team_number_notes', '1236');
277 clickButton('Select');
278
279 for (let i = 1; i <= 3; i++) {
280 // Press Control + i
281 cy.get('body').type(`{ctrl}${i}`);
282
283 // Expect text input to be focused.
284 cy.focused().then(($element) => {
285 expect($element).to.have.id(`text-input-${i}`);
286 });
287 }
288 });
289
290 it('should: submit driver ranking', () => {
291 // Navigate to Driver Ranking Page.
292 switchToTab('Driver Ranking');
293 headerShouldBe('Driver Ranking');
294
295 // Input match and team numbers.
296 setInputTo('#match_number_selection', '11');
297 setInputTo('#team_input_0', '123');
298 setInputTo('#team_input_1', '456');
299 setInputTo('#team_input_2', '789');
300 clickButton('Select');
301
302 // Verify match and team key input.
303 cy.get('#match_number_heading').should('have.text', 'Match #11');
304 cy.get('#team_key_label_0').should('have.text', ' 123 ');
305 cy.get('#team_key_label_1').should('have.text', ' 456 ');
306 cy.get('#team_key_label_2').should('have.text', ' 789 ');
307
308 // Rank teams.
309 cy.get('#up_button_2').click();
310 cy.get('#down_button_0').click();
311
312 // Verify ranking change.
313 cy.get('#team_key_label_0').should('have.text', ' 789 ');
314 cy.get('#team_key_label_1').should('have.text', ' 123 ');
315 cy.get('#team_key_label_2').should('have.text', ' 456 ');
316
317 // Submit.
318 clickButton('Submit');
319 });
320});