Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 1 | /// <reference types="cypress" /> |
| 2 | |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 3 | // On the 87th row of matches (index 86) click on the second team |
| 4 | // (index 1) which resolves to team 5254 in semi final 2 match 3. |
| 5 | const SEMI_FINAL_2_MATCH_3_TEAM_5254 = 86 * 6 + 1; |
| 6 | |
| 7 | // On the 1st row of matches (index 0) click on the fourth team |
| 8 | // (index 3) which resolves to team 3990 in quals match 1. |
| 9 | const QUALS_MATCH_1_TEAM_3990 = 0 * 6 + 3; |
| 10 | |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 11 | function disableAlerts() { |
| 12 | cy.get('#block_alerts').check({force: true}).should('be.checked'); |
| 13 | } |
| 14 | |
| 15 | function switchToTab(tabName) { |
| 16 | cy.contains('.nav-link', tabName).click(); |
| 17 | } |
| 18 | |
| 19 | function headerShouldBe(text) { |
| 20 | cy.get('.header').should('have.text', text); |
| 21 | } |
| 22 | |
| 23 | function clickButton(buttonName) { |
| 24 | cy.contains('button', buttonName).click(); |
| 25 | } |
| 26 | |
| 27 | function setInputTo(fieldSelector, value) { |
| 28 | cy.get(fieldSelector).type('{selectAll}' + value); |
| 29 | } |
| 30 | |
| 31 | // Moves the nth slider left or right. A positive "adjustBy" value moves the |
| 32 | // slider to the right. A negative value moves the slider to the left. |
| 33 | // |
| 34 | // negative/left <--- 0 ---> positive/right |
| 35 | function adjustNthSliderBy(n, adjustBy) { |
| 36 | let element = cy.get('input[type=range]').eq(n); |
| 37 | element.scrollIntoView(); |
| 38 | element.invoke('val').then((currentValue) => { |
| 39 | // We need to query for the slider here again because `invoke('val')` above |
| 40 | // somehow invalidates further calls to `val`. |
| 41 | cy.get('input[type=range]') |
| 42 | .eq(n) |
| 43 | .invoke('val', currentValue + adjustBy) |
| 44 | .trigger('change'); |
| 45 | }); |
| 46 | } |
| 47 | |
| 48 | // Asserts that the field on the "Submit and Review" screen has a specific |
| 49 | // value. |
| 50 | function expectReviewFieldToBe(fieldName, expectedValue) { |
| 51 | expectNthReviewFieldToBe(fieldName, 0, expectedValue); |
| 52 | } |
| 53 | |
| 54 | // Asserts that the n'th instance of a field on the "Submit and Review" |
| 55 | // screen has a specific value. |
| 56 | function expectNthReviewFieldToBe(fieldName, n, expectedValue) { |
| 57 | getNthReviewField(fieldName, n).should( |
| 58 | 'have.text', |
| 59 | `${fieldName}: ${expectedValue}` |
| 60 | ); |
| 61 | } |
| 62 | |
| 63 | function getNthReviewField(fieldName, n) { |
| 64 | let element = cy.get('li').filter(`:contains("${fieldName}: ")`).eq(n); |
| 65 | element.scrollIntoView(); |
| 66 | return element; |
| 67 | } |
| 68 | |
| 69 | before(() => { |
| 70 | cy.visit('/'); |
| 71 | disableAlerts(); |
| 72 | cy.title().should('eq', 'FRC971 Scouting Application'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 73 | }); |
| 74 | |
| 75 | beforeEach(() => { |
| 76 | cy.visit('/'); |
| 77 | disableAlerts(); |
| 78 | }); |
| 79 | |
| 80 | describe('Scouting app tests', () => { |
| 81 | it('should: show matches in chronological order.', () => { |
| 82 | headerShouldBe('Matches'); |
| 83 | cy.get('.badge').eq(0).contains('Quals Match 1'); |
| 84 | cy.get('.badge').eq(1).contains('Quals Match 2'); |
| 85 | cy.get('.badge').eq(2).contains('Quals Match 3'); |
| 86 | cy.get('.badge').eq(9).contains('Quals Match 10'); |
| 87 | cy.get('.badge').eq(72).contains('Quarter Final 1 Match 1'); |
| 88 | cy.get('.badge').eq(73).contains('Quarter Final 2 Match 1'); |
| 89 | cy.get('.badge').eq(74).contains('Quarter Final 3 Match 1'); |
| 90 | cy.get('.badge').eq(75).contains('Quarter Final 4 Match 1'); |
| 91 | cy.get('.badge').eq(76).contains('Quarter Final 1 Match 2'); |
| 92 | cy.get('.badge').eq(82).contains('Semi Final 1 Match 1'); |
| 93 | cy.get('.badge').eq(83).contains('Semi Final 2 Match 1'); |
| 94 | cy.get('.badge').eq(84).contains('Semi Final 1 Match 2'); |
| 95 | cy.get('.badge').eq(85).contains('Semi Final 2 Match 2'); |
| 96 | cy.get('.badge').eq(89).contains('Final 1 Match 3'); |
| 97 | }); |
| 98 | |
Philipp Schrader | 75021f5 | 2023-04-09 21:14:13 -0700 | [diff] [blame] | 99 | it('should: be let users enter match information manually.', () => { |
| 100 | switchToTab('Entry'); |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 101 | headerShouldBe(' Team Selection '); |
Philipp Schrader | 75021f5 | 2023-04-09 21:14:13 -0700 | [diff] [blame] | 102 | |
| 103 | setInputTo('#match_number', '3'); |
| 104 | setInputTo('#team_number', '5254'); |
| 105 | setInputTo('#set_number', '2'); |
| 106 | setInputTo('#comp_level', '3: sf'); |
| 107 | |
| 108 | clickButton('Next'); |
| 109 | |
| 110 | headerShouldBe('5254 Init '); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 111 | }); |
| 112 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 113 | //TODO(FILIP): Verify last action when the last action header gets added. |
Sabina Leaver | 9b4eb31 | 2023-02-20 19:58:17 -0800 | [diff] [blame] | 114 | it('should: be able to submit data scouting.', () => { |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 115 | // Click on a random team in the Match list. The exact details here are not |
| 116 | // important, but we need to know what they are. This could as well be any |
| 117 | // other team from any other match. |
| 118 | cy.get('button.match-item').eq(SEMI_FINAL_2_MATCH_3_TEAM_5254).click(); |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 119 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 120 | // Select Starting Position. |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 121 | headerShouldBe('5254 Init '); |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 122 | cy.get('[type="radio"]').first().check(); |
| 123 | clickButton('Start Match'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 124 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 125 | // Pick and Place Cone in Auto. |
| 126 | clickButton('CONE'); |
| 127 | clickButton('HIGH'); |
| 128 | |
| 129 | // Pick and Place Cube in Teleop. |
| 130 | clickButton('Start Teleop'); |
| 131 | clickButton('CUBE'); |
| 132 | clickButton('LOW'); |
| 133 | |
| 134 | // Robot dead and revive. |
| 135 | clickButton('DEAD'); |
| 136 | clickButton('Revive'); |
| 137 | |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 138 | // Endgame. |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 139 | clickButton('Endgame'); |
| 140 | cy.get('[type="checkbox"]').check(); |
| 141 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 142 | clickButton('End Match'); |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 143 | headerShouldBe('5254 Review and Submit '); |
Sabina Leaver | 9b4eb31 | 2023-02-20 19:58:17 -0800 | [diff] [blame] | 144 | |
| 145 | clickButton('Submit'); |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 146 | headerShouldBe('5254 Success '); |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 147 | |
| 148 | // Now that the data is submitted, the button should be disabled. |
| 149 | switchToTab('Match List'); |
| 150 | cy.get('button.match-item') |
| 151 | .eq(SEMI_FINAL_2_MATCH_3_TEAM_5254) |
| 152 | .should('be.disabled'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 153 | }); |
| 154 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 155 | it('should: be able to return to correct screen with undo for pick and place.', () => { |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 156 | cy.get('button.match-item').eq(QUALS_MATCH_1_TEAM_3990).click(); |
Philipp Schrader | 2b33427 | 2023-04-11 21:27:36 -0700 | [diff] [blame] | 157 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 158 | // Select Starting Position. |
| 159 | cy.get('[type="radio"]').first().check(); |
| 160 | clickButton('Start Match'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 161 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 162 | // Pick up cone. |
| 163 | clickButton('CONE'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 164 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 165 | // Undo that pick up. |
| 166 | clickButton('UNDO'); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 167 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 168 | // User should be back on pickup screen. |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 169 | headerShouldBe('3990 Pickup '); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 170 | |
Filip Kujawa | 2dc9aa6 | 2023-03-04 11:45:01 -0800 | [diff] [blame] | 171 | // Check the same thing but for undoing place. |
| 172 | clickButton('CUBE'); |
| 173 | clickButton('MID'); |
| 174 | clickButton('UNDO'); |
Philipp Schrader | e11114f | 2023-04-15 17:04:25 -0700 | [diff] [blame] | 175 | headerShouldBe('3990 Place '); |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 176 | }); |
| 177 | |
Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 178 | it('should: submit note scouting for multiple teams', () => { |
| 179 | // Navigate to Notes Page. |
| 180 | switchToTab('Notes'); |
| 181 | headerShouldBe('Notes'); |
| 182 | |
| 183 | // Add first team. |
| 184 | setInputTo('#team_number_notes', '1234'); |
| 185 | clickButton('Select'); |
| 186 | |
| 187 | // Add note and select keyword for first team. |
| 188 | cy.get('#team-key-1').should('have.text', '1234'); |
| 189 | setInputTo('#text-input-1', 'Good Driving'); |
| 190 | cy.get('#good_driving_0').click(); |
| 191 | |
| 192 | // Navigate to add team selection and add another team. |
| 193 | clickButton('Add team'); |
| 194 | setInputTo('#team_number_notes', '1235'); |
| 195 | clickButton('Select'); |
| 196 | |
| 197 | // Add note and select keyword for second team. |
| 198 | cy.get('#team-key-2').should('have.text', '1235'); |
| 199 | setInputTo('#text-input-2', 'Bad Driving'); |
| 200 | cy.get('#bad_driving_1').click(); |
| 201 | |
| 202 | // Submit Notes. |
| 203 | clickButton('Submit'); |
| 204 | cy.get('#team_number_label').should('have.text', ' Team Number '); |
| 205 | }); |
| 206 | |
| 207 | it('should: switch note text boxes with keyboard shortcuts', () => { |
| 208 | // Navigate to Notes Page. |
| 209 | switchToTab('Notes'); |
| 210 | headerShouldBe('Notes'); |
| 211 | |
| 212 | // Add first team. |
| 213 | setInputTo('#team_number_notes', '1234'); |
| 214 | clickButton('Select'); |
| 215 | |
| 216 | // Add second team. |
| 217 | clickButton('Add team'); |
| 218 | setInputTo('#team_number_notes', '1235'); |
| 219 | clickButton('Select'); |
| 220 | |
| 221 | // Add third team. |
| 222 | clickButton('Add team'); |
| 223 | setInputTo('#team_number_notes', '1236'); |
| 224 | clickButton('Select'); |
| 225 | |
| 226 | for (let i = 1; i <= 3; i++) { |
| 227 | // Press Control + i |
| 228 | cy.get('body').type(`{ctrl}${i}`); |
| 229 | |
| 230 | // Expect text input to be focused. |
| 231 | cy.focused().then(($element) => { |
| 232 | expect($element).to.have.id(`text-input-${i}`); |
| 233 | }); |
| 234 | } |
| 235 | }); |
| 236 | |
| 237 | it('should: submit driver ranking', () => { |
| 238 | // Navigate to Driver Ranking Page. |
| 239 | switchToTab('Driver Ranking'); |
| 240 | headerShouldBe('Driver Ranking'); |
| 241 | |
| 242 | // Input match and team numbers. |
| 243 | setInputTo('#match_number_selection', '11'); |
| 244 | setInputTo('#team_input_0', '123'); |
| 245 | setInputTo('#team_input_1', '456'); |
| 246 | setInputTo('#team_input_2', '789'); |
| 247 | clickButton('Select'); |
| 248 | |
| 249 | // Verify match and team key input. |
| 250 | cy.get('#match_number_heading').should('have.text', 'Match #11'); |
| 251 | cy.get('#team_key_label_0').should('have.text', ' 123 '); |
| 252 | cy.get('#team_key_label_1').should('have.text', ' 456 '); |
| 253 | cy.get('#team_key_label_2').should('have.text', ' 789 '); |
| 254 | |
| 255 | // Rank teams. |
| 256 | cy.get('#up_button_2').click(); |
| 257 | cy.get('#down_button_0').click(); |
| 258 | |
| 259 | // Verify ranking change. |
| 260 | cy.get('#team_key_label_0').should('have.text', ' 789 '); |
| 261 | cy.get('#team_key_label_1').should('have.text', ' 123 '); |
| 262 | cy.get('#team_key_label_2').should('have.text', ' 456 '); |
| 263 | |
| 264 | // Submit. |
| 265 | clickButton('Submit'); |
| 266 | }); |
| 267 | }); |