blob: d79bf5aadb7df59e1ac3fe2642769cce1fa463fa [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
Philipp Schrader2b334272023-04-11 21:27:36 -070023// Click on a random team in the Match list. The exact details here are not
24// important, but we need to know what they are. This could as well be any
25// other team from any other match.
26function clickSemiFinal2Match3Team5254() {
27 // On the 87th row of matches (index 86) click on the second team
28 // (index 1) which resolves to team 5254 in semi final 2 match 3.
29 cy.get('button.match-item')
30 .eq(86 * 6 + 1)
31 .click();
32}
33
Philipp Schrader175a93c2023-02-19 13:13:40 -080034// Moves the nth slider left or right. A positive "adjustBy" value moves the
35// slider to the right. A negative value moves the slider to the left.
36//
37// negative/left <--- 0 ---> positive/right
38function adjustNthSliderBy(n, adjustBy) {
39 let element = cy.get('input[type=range]').eq(n);
40 element.scrollIntoView();
41 element.invoke('val').then((currentValue) => {
42 // We need to query for the slider here again because `invoke('val')` above
43 // somehow invalidates further calls to `val`.
44 cy.get('input[type=range]')
45 .eq(n)
46 .invoke('val', currentValue + adjustBy)
47 .trigger('change');
48 });
49}
50
51// Asserts that the field on the "Submit and Review" screen has a specific
52// value.
53function expectReviewFieldToBe(fieldName, expectedValue) {
54 expectNthReviewFieldToBe(fieldName, 0, expectedValue);
55}
56
57// Asserts that the n'th instance of a field on the "Submit and Review"
58// screen has a specific value.
59function expectNthReviewFieldToBe(fieldName, n, expectedValue) {
60 getNthReviewField(fieldName, n).should(
61 'have.text',
62 `${fieldName}: ${expectedValue}`
63 );
64}
65
66function getNthReviewField(fieldName, n) {
67 let element = cy.get('li').filter(`:contains("${fieldName}: ")`).eq(n);
68 element.scrollIntoView();
69 return element;
70}
71
72before(() => {
73 cy.visit('/');
74 disableAlerts();
75 cy.title().should('eq', 'FRC971 Scouting Application');
Philipp Schrader175a93c2023-02-19 13:13:40 -080076});
77
78beforeEach(() => {
79 cy.visit('/');
80 disableAlerts();
81});
82
83describe('Scouting app tests', () => {
84 it('should: show matches in chronological order.', () => {
85 headerShouldBe('Matches');
86 cy.get('.badge').eq(0).contains('Quals Match 1');
87 cy.get('.badge').eq(1).contains('Quals Match 2');
88 cy.get('.badge').eq(2).contains('Quals Match 3');
89 cy.get('.badge').eq(9).contains('Quals Match 10');
90 cy.get('.badge').eq(72).contains('Quarter Final 1 Match 1');
91 cy.get('.badge').eq(73).contains('Quarter Final 2 Match 1');
92 cy.get('.badge').eq(74).contains('Quarter Final 3 Match 1');
93 cy.get('.badge').eq(75).contains('Quarter Final 4 Match 1');
94 cy.get('.badge').eq(76).contains('Quarter Final 1 Match 2');
95 cy.get('.badge').eq(82).contains('Semi Final 1 Match 1');
96 cy.get('.badge').eq(83).contains('Semi Final 2 Match 1');
97 cy.get('.badge').eq(84).contains('Semi Final 1 Match 2');
98 cy.get('.badge').eq(85).contains('Semi Final 2 Match 2');
99 cy.get('.badge').eq(89).contains('Final 1 Match 3');
100 });
101
102 it('should: prefill the match information.', () => {
103 headerShouldBe('Matches');
104
Philipp Schrader2b334272023-04-11 21:27:36 -0700105 clickSemiFinal2Match3Team5254();
Philipp Schrader175a93c2023-02-19 13:13:40 -0800106
Philipp Schrader2b334272023-04-11 21:27:36 -0700107 headerShouldBe(' Team Selection ');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800108 cy.get('#match_number').should('have.value', '3');
109 cy.get('#team_number').should('have.value', '5254');
110 cy.get('#set_number').should('have.value', '2');
111 cy.get('#comp_level').should('have.value', '3: sf');
112 });
113
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800114 //TODO(FILIP): Verify last action when the last action header gets added.
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800115 it('should: be able to submit data scouting.', () => {
Philipp Schrader2b334272023-04-11 21:27:36 -0700116 clickSemiFinal2Match3Team5254();
117
118 headerShouldBe(' Team Selection ');
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800119 clickButton('Next');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800120
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800121 // Select Starting Position.
Philipp Schrader2b334272023-04-11 21:27:36 -0700122 headerShouldBe('5254 Init ');
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800123 cy.get('[type="radio"]').first().check();
124 clickButton('Start Match');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800125
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800126 // Pick and Place Cone in Auto.
127 clickButton('CONE');
128 clickButton('HIGH');
129
130 // Pick and Place Cube in Teleop.
131 clickButton('Start Teleop');
132 clickButton('CUBE');
133 clickButton('LOW');
134
135 // Robot dead and revive.
136 clickButton('DEAD');
137 clickButton('Revive');
138
139 // Engame.
140 clickButton('Endgame');
141 cy.get('[type="checkbox"]').check();
142
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800143 clickButton('End Match');
Philipp Schrader2b334272023-04-11 21:27:36 -0700144 headerShouldBe('5254 Review and Submit ');
Sabina Leaver9b4eb312023-02-20 19:58:17 -0800145
146 clickButton('Submit');
Philipp Schrader2b334272023-04-11 21:27:36 -0700147 headerShouldBe('5254 Success ');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800148 });
149
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800150 it('should: be able to return to correct screen with undo for pick and place.', () => {
Philipp Schrader2b334272023-04-11 21:27:36 -0700151 clickSemiFinal2Match3Team5254();
152
153 headerShouldBe(' Team Selection ');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800154 clickButton('Next');
155
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800156 // Select Starting Position.
157 cy.get('[type="radio"]').first().check();
158 clickButton('Start Match');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800159
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800160 // Pick up cone.
161 clickButton('CONE');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800162
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800163 // Undo that pick up.
164 clickButton('UNDO');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800165
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800166 // User should be back on pickup screen.
Philipp Schrader2b334272023-04-11 21:27:36 -0700167 headerShouldBe('5254 Pickup ');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800168
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800169 // Check the same thing but for undoing place.
170 clickButton('CUBE');
171 clickButton('MID');
172 clickButton('UNDO');
Philipp Schrader2b334272023-04-11 21:27:36 -0700173 headerShouldBe('5254 Place ');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800174 });
175
Philipp Schrader175a93c2023-02-19 13:13:40 -0800176 it('should: submit note scouting for multiple teams', () => {
177 // Navigate to Notes Page.
178 switchToTab('Notes');
179 headerShouldBe('Notes');
180
181 // Add first team.
182 setInputTo('#team_number_notes', '1234');
183 clickButton('Select');
184
185 // Add note and select keyword for first team.
186 cy.get('#team-key-1').should('have.text', '1234');
187 setInputTo('#text-input-1', 'Good Driving');
188 cy.get('#good_driving_0').click();
189
190 // Navigate to add team selection and add another team.
191 clickButton('Add team');
192 setInputTo('#team_number_notes', '1235');
193 clickButton('Select');
194
195 // Add note and select keyword for second team.
196 cy.get('#team-key-2').should('have.text', '1235');
197 setInputTo('#text-input-2', 'Bad Driving');
198 cy.get('#bad_driving_1').click();
199
200 // Submit Notes.
201 clickButton('Submit');
202 cy.get('#team_number_label').should('have.text', ' Team Number ');
203 });
204
205 it('should: switch note text boxes with keyboard shortcuts', () => {
206 // Navigate to Notes Page.
207 switchToTab('Notes');
208 headerShouldBe('Notes');
209
210 // Add first team.
211 setInputTo('#team_number_notes', '1234');
212 clickButton('Select');
213
214 // Add second team.
215 clickButton('Add team');
216 setInputTo('#team_number_notes', '1235');
217 clickButton('Select');
218
219 // Add third team.
220 clickButton('Add team');
221 setInputTo('#team_number_notes', '1236');
222 clickButton('Select');
223
224 for (let i = 1; i <= 3; i++) {
225 // Press Control + i
226 cy.get('body').type(`{ctrl}${i}`);
227
228 // Expect text input to be focused.
229 cy.focused().then(($element) => {
230 expect($element).to.have.id(`text-input-${i}`);
231 });
232 }
233 });
234
235 it('should: submit driver ranking', () => {
236 // Navigate to Driver Ranking Page.
237 switchToTab('Driver Ranking');
238 headerShouldBe('Driver Ranking');
239
240 // Input match and team numbers.
241 setInputTo('#match_number_selection', '11');
242 setInputTo('#team_input_0', '123');
243 setInputTo('#team_input_1', '456');
244 setInputTo('#team_input_2', '789');
245 clickButton('Select');
246
247 // Verify match and team key input.
248 cy.get('#match_number_heading').should('have.text', 'Match #11');
249 cy.get('#team_key_label_0').should('have.text', ' 123 ');
250 cy.get('#team_key_label_1').should('have.text', ' 456 ');
251 cy.get('#team_key_label_2').should('have.text', ' 789 ');
252
253 // Rank teams.
254 cy.get('#up_button_2').click();
255 cy.get('#down_button_0').click();
256
257 // Verify ranking change.
258 cy.get('#team_key_label_0').should('have.text', ' 789 ');
259 cy.get('#team_key_label_1').should('have.text', ' 123 ');
260 cy.get('#team_key_label_2').should('have.text', ' 456 ');
261
262 // Submit.
263 clickButton('Submit');
264 });
265});