Cypress: Select random enum value

Viewed 919

I've got a bunch of enums in my Cypress tests, and I want to randomize some of them. When I'm using Kotlin, for instance, it's a no-brainer. However, I haven't been able to with Cypress/TypeScript and my very limited knowledge of the language.

The enum can have the following values: Purpose.BUILD, Purpose.BUY, Purpose.REBUILD

Here's what I've got so far, picked from somewhere I cannot remember at this moment (maybe StackOverflow?):

randomEnum<T>(anEnum: T): T[keyof T] {
  const enumValues = Object.keys(anEnum)
    .map(n => Number.parseInt(n))
    .filter(n => !Number.isNaN(n)) as unknown as T[keyof T][]
  const randomIndex = Math.floor(Math.random() * enumValues.length)
  return enumValues[randomIndex];
}

Called with:

const Purpose = ProsjektfinansieringTO.FinansieringsProdukterEnum;

// Get a random value for Purpose:
let purpose: FinansieringsProdukterEnum = this.randomEnum(Porpose);
// Select the apporpriate choice on the page:
purposePage.setPurpose(purpose);         // Doesn't work
//purposePage.setPurpose(Purpose.BUY);   // Works.
   

As far as I can see, the randomEnum() function doesen't return an enum. Since the line below, which is commented out, works I believe the error to be with the randomEnum() function.

Any hints? What am I missing? Is it really this complicated?

TAKE 2:

With a little more understanding of the code, I've tried to use it the way it's intended. I get a random enum value numer from the randomEnum() method, and I try to select the page element based on that. However, I still cannot get it to work. It works when specifying an enum value instead of getting the random one.

setRandomPurpose() {
  let purpose: FinansieringsProdukterEnum = this.randomEnum(Purpose);
  
  purposePage.setPurpose(Purpose[purpose]); // Doesn't work.
  //purposePage.setPurpose(Purpose.BUY);    // THIS works.
}

randomEnum<T>(anEnum: T): T[keyof T] {
  const enumValues = Object.keys(anEnum)
    .map(n => Number.parseInt(n))
    .filter(n => !Number.isNaN(n)) as unknown as T[keyof T][]
  const randomIndex = Math.floor(Math.random() * enumValues.length)
  return enumValues[randomIndex];
}

The purposePage class:

import FinansieringsProdukterEnum = ProsjektfinansieringTO.FinansieringsProdukterEnum;

public setPurpose(Purpose: FinansieringsProdukterEnum) {
cy.pause();

switch (formal) {
  case "BUY": this.buyRadioLabel.click();
    break;
  case "REBUILD": this.rebuildRadioLabel.click();
    break;
  case "BUILD": this.buildRadioLabel.click();
    break;
  }
  cy.pause();
}      

TAKE 3

The "working" class:

import FinansieringsProdukterEnum =    ProsjektfinansieringTO.FinansieringsProdukterEnum;
const Purpose = ProsjektfinansieringTO.FinansieringsProdukterEnum;

export class PurposeWorkflow {
  setRandomPurpose() {
    let purpose: FinansieringsProdukterEnum = this.randomEnum(Purpose);
    purposePage.setPurpose(purpose);
  }
}

import FinansieringsProdukterEnum = ProsjektfinansieringTO.FinansieringsProdukterEnum;

public setPurpose((purpose: FinansieringsProdukterEnum) {
  switch (FinansieringsProdukterEnum[(purpose]) {
    case "BUY": this.buyRadioLabel.click();
      console.log('buyRadioLabel');
      cy.pause();
      break;
    case "REBUILD": this.rebuildRadioLabel.click();
      console.log('rebuildgRadioLabel');
      cy.pause();
      break;
    case "BUILD": this.buildRadioLabel.click();
      console.log('oppforingRadioLabel');
      cy.pause();
      break;
  }
}

This doesn't work. Note that I'm using cy.pause() just to check that the conditions are mathced, which they never are. I'm having trouble with console.log() beause I have to use the Electron browser with Cypress. It's very buggy. But, using the cy.pause() lines nevertheless should indicate where in the code I am.

I've also tried this in the "working class":

setRandomFormal() {
    let formal: FinansieringsProdukterEnum = this.randomEnum(Formal);
    console.log(formal);          //Both of these shows "undefined.
    //console.log(Forma[formal]);
}

TAKE 4

I'm beginning to wonder if the problem might be related to the type of Enum I'm using...

export interface ProsjektfinansieringTO { 
   // Removed lots of variables for simplicity's sake.
}
export namespace ProsjektfinansieringTO {
  export type FinansieringsProdukterEnum = 'BUILD' | 'BUY' | 'REBUILD';
  export const FinansieringsProdukterEnum = {
    BUILD: _('BUILD') as FinansieringsProdukterEnum,
    BUY: _('BUY') as FinansieringsProdukterEnum,
    REBUILD: _('REBUILD') as FinansieringsProdukterEnum,
  };
}

Troubleshoooting:

In the same "working" code, I've added the following two enums locally, to try and isolate the cause of the "undefined" error:

enum PrintMedia {
  Newspaper,
  Newsletter,
  Magazine,
  Book
}

export type FinansieringsProdukterEnum2 = 'BUILD' | 'BUY' | 'REBUILD';
const FinansieringsProdukterEnum2 = {
  BUILD: ('BUILD') as FinansieringsProdukterEnum2,
  BUY: ('BUY') as FinansieringsProdukterEnum2,
  REBUILD: ('REBUILD') as FinansieringsProdukterEnum2
};

// Works:    
let printmedia: PrintMedia = this.randomEnum(PrintMedia);
console.log('Printmedia: ' + PrintMedia[printmedia]);

// Doesn't work: ('undefined')
let purpose2 = this.randomEnum(FinansieringsProdukterEnum2);
console.log('FinansieringsProdukterEnum2: ' + FinansieringsProdukterEnum2[purpose2]); 
0 Answers
Related