blob: 0237c4bbabd42a509116839588f950f4b553043c [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 Kujawa2dc9aa62023-03-04 11:45:01 -0800107 //TODO(FILIP): Verify last action when the last action header gets added.
108 it('should: be able to get to submit screen in data scouting.', () => {
Philipp Schrader175a93c2023-02-19 13:13:40 -0800109 switchToTab('Data Entry');
110 headerShouldBe('Team Selection');
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800111 clickButton('Next');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800112
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800113 // Select Starting Position.
114 cy.get('[type="radio"]').first().check();
115 clickButton('Start Match');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800116
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800117 // Pick and Place Cone in Auto.
118 clickButton('CONE');
119 clickButton('HIGH');
120
121 // Pick and Place Cube in Teleop.
122 clickButton('Start Teleop');
123 clickButton('CUBE');
124 clickButton('LOW');
125
126 // Robot dead and revive.
127 clickButton('DEAD');
128 clickButton('Revive');
129
130 // Engame.
131 clickButton('Endgame');
132 cy.get('[type="checkbox"]').check();
133
134 // Should be on submit screen.
135 // TODO(FILIP): Verify that submitting works once we add it.
136
137 clickButton('End Match');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800138 headerShouldBe('Review and Submit');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800139 });
140
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800141 it('should: be able to return to correct screen with undo for pick and place.', () => {
Philipp Schrader175a93c2023-02-19 13:13:40 -0800142 switchToTab('Data Entry');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800143 headerShouldBe('Team Selection');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800144 clickButton('Next');
145
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800146 // Select Starting Position.
147 cy.get('[type="radio"]').first().check();
148 clickButton('Start Match');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800149
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800150 // Pick up cone.
151 clickButton('CONE');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800152
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800153 // Undo that pick up.
154 clickButton('UNDO');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800155
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800156 // User should be back on pickup screen.
157 headerShouldBe('Pickup');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800158
Filip Kujawa2dc9aa62023-03-04 11:45:01 -0800159 // Check the same thing but for undoing place.
160 clickButton('CUBE');
161 clickButton('MID');
162 clickButton('UNDO');
163 headerShouldBe('Place');
Philipp Schrader175a93c2023-02-19 13:13:40 -0800164 });
165
Philipp Schrader175a93c2023-02-19 13:13:40 -0800166 it('should: submit note scouting for multiple teams', () => {
167 // Navigate to Notes Page.
168 switchToTab('Notes');
169 headerShouldBe('Notes');
170
171 // Add first team.
172 setInputTo('#team_number_notes', '1234');
173 clickButton('Select');
174
175 // Add note and select keyword for first team.
176 cy.get('#team-key-1').should('have.text', '1234');
177 setInputTo('#text-input-1', 'Good Driving');
178 cy.get('#good_driving_0').click();
179
180 // Navigate to add team selection and add another team.
181 clickButton('Add team');
182 setInputTo('#team_number_notes', '1235');
183 clickButton('Select');
184
185 // Add note and select keyword for second team.
186 cy.get('#team-key-2').should('have.text', '1235');
187 setInputTo('#text-input-2', 'Bad Driving');
188 cy.get('#bad_driving_1').click();
189
190 // Submit Notes.
191 clickButton('Submit');
192 cy.get('#team_number_label').should('have.text', ' Team Number ');
193 });
194
195 it('should: switch note text boxes with keyboard shortcuts', () => {
196 // Navigate to Notes Page.
197 switchToTab('Notes');
198 headerShouldBe('Notes');
199
200 // Add first team.
201 setInputTo('#team_number_notes', '1234');
202 clickButton('Select');
203
204 // Add second team.
205 clickButton('Add team');
206 setInputTo('#team_number_notes', '1235');
207 clickButton('Select');
208
209 // Add third team.
210 clickButton('Add team');
211 setInputTo('#team_number_notes', '1236');
212 clickButton('Select');
213
214 for (let i = 1; i <= 3; i++) {
215 // Press Control + i
216 cy.get('body').type(`{ctrl}${i}`);
217
218 // Expect text input to be focused.
219 cy.focused().then(($element) => {
220 expect($element).to.have.id(`text-input-${i}`);
221 });
222 }
223 });
224
225 it('should: submit driver ranking', () => {
226 // Navigate to Driver Ranking Page.
227 switchToTab('Driver Ranking');
228 headerShouldBe('Driver Ranking');
229
230 // Input match and team numbers.
231 setInputTo('#match_number_selection', '11');
232 setInputTo('#team_input_0', '123');
233 setInputTo('#team_input_1', '456');
234 setInputTo('#team_input_2', '789');
235 clickButton('Select');
236
237 // Verify match and team key input.
238 cy.get('#match_number_heading').should('have.text', 'Match #11');
239 cy.get('#team_key_label_0').should('have.text', ' 123 ');
240 cy.get('#team_key_label_1').should('have.text', ' 456 ');
241 cy.get('#team_key_label_2').should('have.text', ' 789 ');
242
243 // Rank teams.
244 cy.get('#up_button_2').click();
245 cy.get('#down_button_0').click();
246
247 // Verify ranking change.
248 cy.get('#team_key_label_0').should('have.text', ' 789 ');
249 cy.get('#team_key_label_1').should('have.text', ' 123 ');
250 cy.get('#team_key_label_2').should('have.text', ' 456 ');
251
252 // Submit.
253 clickButton('Submit');
254 });
255});