@@ -6,23 +6,23 @@ import ClusterManagerEditGenericPagePo from '@/cypress/e2e/po/edit/provisioning.
66import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po' ;
77import LoadingPo from '@/cypress/e2e/po/components/loading.po' ;
88import TabbedPo from '@/cypress/e2e/po/components/tabbed.po' ;
9- import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts' ;
9+ import { LONG_TIMEOUT_OPT , MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts' ;
1010import { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints' ;
11+ import { promptModal } from '@/cypress/e2e/po/prompts/shared/modalInstances.po' ;
1112
1213// will only run this in jenkins pipeline where cloud credentials are stored
13- describe ( 'Deploy RKE2 cluster using node driver on Amazon EC2' , { testIsolation : 'off' , tags : [ '@manager' , '@adminUser' , '@standardUser' , '@jenkins' ] } , ( ) => {
14+ describe ( 'Deploy RKE2 cluster using node driver on Amazon EC2' , { tags : [ '@manager' , '@adminUser' , '@standardUser' , '@jenkins' ] } , ( ) => {
1415 const clusterList = new ClusterManagerListPagePo ( ) ;
1516 const loadingPo = new LoadingPo ( '.loading-indicator' ) ;
1617
1718 let removeCloudCred = false ;
1819 let cloudcredentialId = '' ;
19- let k8sVersion = '' ;
20+ let latestK8sVersion = '' ;
2021 let olderK8sVersion = '' ;
2122 let clusterId = '' ;
2223
2324 before ( ( ) => {
2425 cy . login ( ) ;
25- HomePagePo . goTo ( ) ;
2626
2727 // clean up amazon cloud credentials
2828 cy . getRancherResource ( 'v3' , 'cloudcredentials' , null , null ) . then ( ( resp : Cypress . Response < any > ) => {
@@ -43,6 +43,8 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
4343 } ) ;
4444
4545 beforeEach ( ( ) => {
46+ cy . login ( ) ;
47+ HomePagePo . goTo ( ) ;
4648 cy . createE2EResourceName ( 'rke2ec2cluster' ) . as ( 'rke2Ec2ClusterName' ) ;
4749 cy . createE2EResourceName ( 'ec2cloudcredential' ) . as ( 'ec2CloudCredentialName' ) ;
4850 } ) ;
@@ -85,47 +87,48 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
8587 createRKE2ClusterPage . nameNsDescription ( ) . name ( ) . set ( this . rke2Ec2ClusterName ) ;
8688 createRKE2ClusterPage . nameNsDescription ( ) . description ( ) . set ( `${ this . rke2Ec2ClusterName } -description` ) ;
8789
88- // Get kubernetes versions - use an older version for initial creation, then upgrade later
89- cy . wait ( '@getRke2Releases' ) . then ( ( { response } ) => {
90- expect ( response . statusCode ) . to . eq ( 200 ) ;
91- const index1 = response . body . data . length - 1 ;
92-
93- // Store the latest version for upgrade test
94- k8sVersion = response . body . data [ index1 ] . id ;
95- cy . wrap ( k8sVersion ) . as ( 'k8sVersion' ) ;
90+ // Get kubernetes versions from the UI dropdown
91+ // Index 0 is the "RKE2" header, so actual versions start at index 1
92+ cy . wait ( '@getRke2Releases' ) . its ( 'response.statusCode' ) . should ( 'eq' , 200 ) ;
93+ createRKE2ClusterPage . basicsTab ( ) . kubernetesVersions ( ) . toggle ( ) ;
94+ createRKE2ClusterPage . basicsTab ( ) . kubernetesVersions ( ) . getOptions ( ) . then ( ( $options ) => {
95+ // First RKE2 version (index 1) is the latest version
96+ latestK8sVersion = Cypress . $ ( $options [ 1 ] ) . text ( ) . trim ( ) ;
97+ cy . wrap ( latestK8sVersion ) . as ( 'latestK8sVersion' ) ;
98+
99+ // Second RKE2 version (index 2) is the older version for cluster creation
100+ olderK8sVersion = Cypress . $ ( $options [ 2 ] ) . text ( ) . trim ( ) ;
101+ cy . wrap ( olderK8sVersion ) . as ( 'olderK8sVersion' ) ;
96102
97- // Use the older version for cluster creation
98- // This allows us to test the upgrade scenario
99- const index2 = index1 - 1 ;
103+ cy . log ( `latestK8sVersion: ${ latestK8sVersion } ` ) ;
104+ cy . log ( `olderK8sVersion: ${ olderK8sVersion } ` ) ;
100105
101- olderK8sVersion = response . body . data [ index2 ] . id ;
102- cy . wrap ( olderK8sVersion ) . as ( ' olderK8sVersion' ) ;
106+ // Set the k8s version
107+ createRKE2ClusterPage . basicsTab ( ) . kubernetesVersions ( ) . clickOptionWithLabel ( olderK8sVersion ) ;
103108 } ) ;
104109
105- cy . get < string > ( '@olderK8sVersion' ) . then ( ( version ) => {
106- createRKE2ClusterPage . basicsTab ( ) . kubernetesVersions ( ) . toggle ( ) ;
107- createRKE2ClusterPage . basicsTab ( ) . kubernetesVersions ( ) . clickOptionWithLabel ( version ) ;
108-
109- createRKE2ClusterPage . machinePoolTab ( ) . networks ( ) . toggle ( ) ;
110- createRKE2ClusterPage . machinePoolTab ( ) . networks ( ) . clickOptionWithLabel ( 'default' ) ;
111-
112- cy . intercept ( 'POST' , 'v1/provisioning.cattle.io.clusters' ) . as ( 'createRke2Cluster' ) ;
113- createRKE2ClusterPage . create ( ) ;
114- cy . wait ( '@createRke2Cluster' ) . then ( ( { response } ) => {
115- expect ( response ?. statusCode ) . to . eq ( 201 ) ;
116- expect ( response ?. body ) . to . have . property ( 'kind' , 'Cluster' ) ;
117- expect ( response ?. body . metadata ) . to . have . property ( 'name' , this . rke2Ec2ClusterName ) ;
118- expect ( response ?. body . spec ) . to . have . property ( 'kubernetesVersion' ) . contains ( version ) ;
119- clusterId = response ?. body . id ;
120- } ) ;
121- clusterList . waitForPage ( ) ;
122- clusterList . list ( ) . state ( this . rke2Ec2ClusterName ) . should ( 'be.visible' )
123- . and ( ( $el ) => {
124- const status = $el . text ( ) . trim ( ) ;
110+ // Set the network
111+ createRKE2ClusterPage . machinePoolTab ( ) . networks ( ) . toggle ( ) ;
112+ createRKE2ClusterPage . machinePoolTab ( ) . networks ( ) . clickOptionWithLabel ( 'default' ) ;
125113
126- expect ( [ 'Reconciling' , 'Updating' ] ) . to . include ( status ) ;
127- } ) ;
114+ // Create the cluster
115+ cy . intercept ( 'POST' , 'v1/provisioning.cattle.io.clusters' ) . as ( 'createRke2Cluster' ) ;
116+ createRKE2ClusterPage . create ( ) ;
117+ cy . wait ( '@createRke2Cluster' ) . then ( ( { response } ) => {
118+ expect ( response ?. statusCode ) . to . eq ( 201 ) ;
119+ expect ( response ?. body ) . to . have . property ( 'kind' , 'Cluster' ) ;
120+ expect ( response ?. body . metadata ) . to . have . property ( 'name' , this . rke2Ec2ClusterName ) ;
121+ expect ( response ?. body . spec ) . to . have . property ( 'kubernetesVersion' ) . contains ( olderK8sVersion ) ;
122+ clusterId = response ?. body . id ;
128123 } ) ;
124+
125+ clusterList . waitForPage ( ) ;
126+ clusterList . list ( ) . state ( this . rke2Ec2ClusterName ) . should ( 'be.visible' )
127+ . and ( ( $el ) => {
128+ const status = $el . text ( ) . trim ( ) ;
129+
130+ expect ( [ 'Reconciling' , 'Updating' ] ) . to . include ( status ) ;
131+ } ) ;
129132 } ) ;
130133
131134 it ( 'can see details of cluster in cluster list' , function ( ) {
@@ -164,13 +167,8 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
164167 clusterList . list ( ) . name ( this . rke2Ec2ClusterName ) . click ( ) ;
165168 clusterDetails . waitForPage ( null , 'machine-pools' ) ;
166169 clusterDetails . resourceDetail ( ) . title ( ) . should ( 'contain' , this . rke2Ec2ClusterName ) ;
167- clusterDetails . machinePoolsList ( ) . details ( `${ this . rke2Ec2ClusterName } -pool1-` , 1 ) . should ( 'contain' , 'Running' ) ;
168170
169171 // check cluster details page > recent events
170- ClusterManagerListPagePo . navTo ( ) ;
171- clusterList . waitForPage ( ) ;
172- clusterList . goToDetailsPage ( this . rke2Ec2ClusterName , '.cluster-link a' ) ;
173- clusterDetails . waitForPage ( null , 'machine-pools' ) ;
174172 clusterDetails . selectTab ( tabbedPo , '[data-testid="btn-events"]' ) ;
175173 clusterDetails . waitForPage ( null , 'events' ) ;
176174 clusterDetails . recentEventsList ( ) . checkTableIsEmpty ( ) ;
@@ -192,7 +190,7 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
192190
193191 // Select the latest version for upgrade
194192 editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . toggle ( ) ;
195- editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . clickOptionWithLabel ( k8sVersion ) ;
193+ editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . clickOptionWithLabel ( latestK8sVersion ) ;
196194
197195 cy . intercept ( 'PUT' , `/v1/provisioning.cattle.io.clusters/fleet-default/${ this . rke2Ec2ClusterName } ` ) . as ( 'clusterUpdate' ) ;
198196 // Save the cluster to upgrade the Kubernetes version
@@ -212,7 +210,7 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
212210 expect ( response ?. statusCode ) . to . equal ( 200 ) ;
213211 expect ( response ?. body ) . to . have . property ( 'kind' , 'Cluster' ) ;
214212 expect ( response ?. body . metadata ) . to . have . property ( 'name' , this . rke2Ec2ClusterName ) ;
215- expect ( response ?. body . spec ) . to . have . property ( 'kubernetesVersion' ) . contains ( k8sVersion ) ;
213+ expect ( response ?. body . spec ) . to . have . property ( 'kubernetesVersion' ) . contains ( latestK8sVersion ) ;
216214 } ) ;
217215
218216 clusterList . waitForPage ( ) ;
@@ -221,15 +219,15 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
221219
222220 // check k8s version
223221 clusterList . list ( ) . version ( this . rke2Ec2ClusterName ) . then ( ( el ) => {
224- expect ( el . text ( ) . trim ( ) ) . contains ( k8sVersion ) ;
222+ expect ( el . text ( ) . trim ( ) ) . contains ( latestK8sVersion ) ;
225223 } ) ;
226224
227225 // Navigate back to edit page to verify older version is disabled in dropdown
228226 clusterList . list ( ) . actionMenu ( this . rke2Ec2ClusterName ) . getMenuItem ( 'Edit Config' ) . click ( ) ;
229227 editClusterPage . waitForPage ( 'mode=edit' , 'basic' ) ;
230228
231229 // Verify current version is selected
232- editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . checkContainsOptionSelected ( k8sVersion ) ;
230+ editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . checkContainsOptionSelected ( latestK8sVersion ) ;
233231
234232 // Open dropdown and verify older version is disabled
235233 editClusterPage . basicsTab ( ) . kubernetesVersions ( ) . toggle ( ) ;
@@ -268,6 +266,116 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
268266 clusterDetails . snapshotsList ( ) . checkSnapshotExist ( `on-demand-${ this . rke2Ec2ClusterName } ` ) ;
269267 } ) ;
270268
269+ it ( 'can scale up a machine pool' , function ( ) {
270+ // testing https://github.com/rancher/dashboard/issues/13285
271+ const clusterDetails = new ClusterManagerDetailRke2AmazonEc2PagePo ( undefined , this . rke2Ec2ClusterName ) ;
272+
273+ ClusterManagerListPagePo . navTo ( ) ;
274+ clusterList . waitForPage ( ) ;
275+
276+ // Navigate to cluster details page > machine pools
277+ clusterList . list ( ) . name ( this . rke2Ec2ClusterName ) . click ( ) ;
278+ clusterDetails . waitForPage ( null , 'machine-pools' ) ;
279+ clusterDetails . resourceDetail ( ) . title ( ) . should ( 'contain' , this . rke2Ec2ClusterName ) ;
280+
281+ // Verify scaling buttons are present in the machine pools section
282+ clusterDetails . machinePoolsList ( ) . resourceTable ( ) . sortableTable ( ) . groupByButtons ( 1 )
283+ . click ( ) ;
284+
285+ // Check for scale up button (it should be enabled)
286+ clusterDetails . machinePoolsList ( ) . scaleUpButton ( `${ this . rke2Ec2ClusterName } -pool1` )
287+ . should ( 'be.visible' )
288+ . and ( 'be.enabled' ) ;
289+
290+ // Hover scale up button - tooltip should read "Scale Pool Up"
291+ clusterDetails . machinePoolsList ( ) . scaleButtonTooltip ( `${ this . rke2Ec2ClusterName } -pool1` , 'plus' )
292+ . waitForTooltipWithText ( 'Scale Pool Up' ) ;
293+ clusterDetails . machinePoolsList ( ) . scaleButtonTooltip ( `${ this . rke2Ec2ClusterName } -pool1` , 'plus' )
294+ . hideTooltip ( ) ;
295+
296+ // Check for scale down button (it should be disabled initially)
297+ clusterDetails . machinePoolsList ( ) . scaleDownButton ( `${ this . rke2Ec2ClusterName } -pool1` )
298+ . should ( 'be.visible' )
299+ . and ( 'be.disabled' ) ;
300+
301+ // Hover scale down button - tooltip should read "Scale Pool Down"
302+ clusterDetails . machinePoolsList ( ) . scaleButtonTooltip ( `${ this . rke2Ec2ClusterName } -pool1` , 'minus' )
303+ . waitForTooltipWithText ( 'Scale Pool Down' ) ;
304+ clusterDetails . machinePoolsList ( ) . scaleButtonTooltip ( `${ this . rke2Ec2ClusterName } -pool1` , 'minus' )
305+ . hideTooltip ( ) ;
306+
307+ cy . intercept ( 'PUT' , ` /v1/provisioning.cattle.io.clusters/fleet-default/${ this . rke2Ec2ClusterName } ` ) . as ( 'scaleUpMachineDeployment' ) ;
308+ // Scale up the machine pool
309+ clusterDetails . machinePoolsList ( ) . scaleUpButton ( `${ this . rke2Ec2ClusterName } -pool1` )
310+ . click ( ) ;
311+
312+ cy . wait ( '@scaleUpMachineDeployment' ) . its ( 'response.statusCode' ) . should ( 'eq' , 200 ) ;
313+
314+ // Verify the machine pool is scaled up to 2
315+ clusterDetails . machinePoolsList ( ) . machinePoolCount ( `${ this . rke2Ec2ClusterName } -pool1` , / ^ 2 $ / , { timeout : 700000 } ) ;
316+ clusterDetails . machinePoolsList ( ) . resourceTable ( ) . sortableTable ( ) . checkRowCount ( false , 2 , LONG_TIMEOUT_OPT ) ;
317+
318+ // Verify the scale down button is now enabled (since we have 2 nodes)
319+ clusterDetails . machinePoolsList ( ) . scaleDownButton ( `${ this . rke2Ec2ClusterName } -pool1` )
320+ . should ( 'be.enabled' ) ;
321+
322+ // Verify the cluster is active
323+ clusterDetails . resourceDetail ( ) . masthead ( ) . resourceStatus ( ) . contains ( 'Active' , { timeout : 700000 } ) ;
324+ clusterDetails . machinePoolsList ( ) . resourceTable ( ) . sortableTable ( ) . checkRowCount ( false , 2 , MEDIUM_TIMEOUT_OPT ) ;
325+ } ) ;
326+
327+ it ( 'can scale down a machine pool' , function ( ) {
328+ // testing https://github.com/rancher/dashboard/issues/13285
329+ // Set user preference to ensure the scale down confirmation modal always appears
330+ cy . setUserPreference ( { 'scale-pool-prompt' : false } ) ;
331+
332+ const clusterDetails = new ClusterManagerDetailRke2AmazonEc2PagePo ( undefined , this . rke2Ec2ClusterName ) ;
333+
334+ ClusterManagerListPagePo . navTo ( ) ;
335+ clusterList . waitForPage ( ) ;
336+
337+ // Navigate to cluster details page > machine pools
338+ clusterList . list ( ) . name ( this . rke2Ec2ClusterName ) . click ( ) ;
339+ clusterDetails . waitForPage ( null , 'machine-pools' ) ;
340+ clusterDetails . resourceDetail ( ) . title ( ) . should ( 'contain' , this . rke2Ec2ClusterName ) ;
341+
342+ // Verify we have 2 nodes to start with (from the previous scale up test)
343+ clusterDetails . machinePoolsList ( ) . resourceTable ( ) . sortableTable ( ) . groupByButtons ( 1 )
344+ . click ( ) ;
345+
346+ clusterDetails . machinePoolsList ( ) . machinePoolCount ( `${ this . rke2Ec2ClusterName } -pool1` , 2 , MEDIUM_TIMEOUT_OPT ) ;
347+
348+ // Verify the scale down button is enabled
349+ clusterDetails . machinePoolsList ( ) . scaleDownButton ( `${ this . rke2Ec2ClusterName } -pool1` )
350+ . should ( 'be.visible' )
351+ . and ( 'be.enabled' ) ;
352+
353+ cy . intercept ( 'PUT' , `/v1/provisioning.cattle.io.clusters/fleet-default/${ this . rke2Ec2ClusterName } ` ) . as ( 'scaleDownMachineDeployment' ) ;
354+
355+ // Scale down the machine pool
356+ clusterDetails . machinePoolsList ( ) . scaleDownButton ( `${ this . rke2Ec2ClusterName } -pool1` )
357+ . click ( ) ;
358+
359+ // Handle the scale down confirmation dialog
360+ promptModal ( ) . getBody ( ) . should ( 'contain' , 'You are attempting to delete the MachineDeployment' ) ;
361+ promptModal ( ) . getBody ( ) . should ( 'contain' , `${ this . rke2Ec2ClusterName } -pool1` ) ;
362+ promptModal ( ) . clickActionButton ( 'Confirm' ) ;
363+
364+ cy . wait ( '@scaleDownMachineDeployment' ) . its ( 'response.statusCode' ) . should ( 'eq' , 200 ) ;
365+
366+ // Verify the machine pool is scaled down to 1
367+ clusterDetails . machinePoolsList ( ) . machinePoolCount ( `${ this . rke2Ec2ClusterName } -pool1` , / ^ 1 $ / , MEDIUM_TIMEOUT_OPT ) ;
368+
369+ // Verify the cluster is updating -> active
370+ clusterDetails . resourceDetail ( ) . masthead ( ) . resourceStatus ( ) . contains ( 'Updating' ) ;
371+ clusterDetails . resourceDetail ( ) . masthead ( ) . resourceStatus ( ) . contains ( 'Active' , { timeout : 700000 } ) ;
372+ clusterDetails . machinePoolsList ( ) . resourceTable ( ) . sortableTable ( ) . checkRowCount ( false , 1 , { timeout : 700000 } ) ;
373+
374+ // Verify the scale down button is now disabled (can't scale below 1)
375+ clusterDetails . machinePoolsList ( ) . scaleDownButton ( `${ this . rke2Ec2ClusterName } -pool1` )
376+ . should ( 'be.disabled' ) ;
377+ } ) ;
378+
271379 it ( 'can delete an Amazon EC2 RKE2 cluster' , function ( ) {
272380 ClusterManagerListPagePo . navTo ( ) ;
273381 clusterList . waitForPage ( ) ;
0 commit comments