-1

I am trying to create a tool that enters assessment marks into a system. I currently have it working but the code is very repetitive. I have a JSON file with the student's marks. I then loop through the length of the data and enter the values into the respective inputs. Once I have finished, I submit and go to the next assessment. How can I reduce the amount of duplication?

const data = require('data.json')

module.exports = {
  '@tags': ['Assessment'],
  'Enter data for each page'(browser) {
    const courseActionLink =
      '#DataModel_DataLinks_YourAssessments__Data_1__Items_READYTOMARK__Value'
    const submitBtn = '[aria-label="Submit Results"]'
    const nextAssessmentBtn = '[aria-label="Next Assessment"]'
    const alertBtn = '#alert-close'

    for (let d = 0; d < data.length; d++) {
      // Mark Assessment Results
      const personCode = `#DataModel_DataLinks_LearnerAssessments__Data_${d}__Items_RESULT_MARKSOUTOF__Value`
      browser
        .clearValue(personCode)
        .setValue(personCode, data[d].a1total)
        .pause(5000)
    }

    browser
      .click(submitBtn)
      .pause(5000)
      .click(alertBtn)
      .pause(5000)
      .click(nextAssessmentBtn)
      .pause(5000)

    for (let d = 0; d < data.length; d++) {
      // Mark Assessment Results
      const personCode = `#DataModel_DataLinks_LearnerAssessments__Data_${d}__Items_RESULT_MARKSOUTOF__Value`
      browser
        .clearValue(personCode)
        .setValue(personCode, data[d].sbatotal)
        .pause(5000)
    }

    browser
      .click(submitBtn)
      .pause(5000)
      .click(alertBtn)
      .pause(5000)
      .click(nextAssessmentBtn)
      .pause(5000)

    for (let d = 0; d < data.length; d++) {
      // Mark Assessment Results
      const personCode = `#DataModel_DataLinks_LearnerAssessments__Data_${d}__Items_RESULT_MARKSOUTOF__Value`
      browser
        .clearValue(personCode)
        .setValue(personCode, data[d].practicalstotal)
        .pause(5000)
    }

    browser
      .click(submitBtn)
      .pause(5000)
      .click(alertBtn)
      .pause(5000)
      .click(nextAssessmentBtn)
      .pause(5000)

    for (let d = 0; d < data.length; d++) {
      // Mark Assessment Results
      const personCode = `#DataModel_DataLinks_LearnerAssessments__Data_${d}__Items_RESULT_MARKSOUTOF__Value`
      browser
        .clearValue(personCode)
        .setValue(personCode, data[d].a2total)
        .pause(5000)
    }

    browser
      .click(submitBtn)
      .pause(5000)
      .click(alertBtn)
      .pause(5000)
  }
}
  • First question is how many times will you need to do it? Is that a static or dynamic number? If it's a static number then you can try throwing all of that code you already have in a `while` loop. If the number is dynamic, is there a way to return that number through another method? – king_wayne Dec 02 '19 at 17:44

1 Answers1

1

There are 2 good opportunities for refactoring that I see:

1) Create this function:

const clickButtons = function(clickNext) {
  browser
    .click(submitBtn)
    .pause(5000)
    .click(alertBtn)
    .pause(5000)
  if(clickNext) {
    browser
      .click(nextAssessmentBtn)
      .pause(5000)
  }
}

Obviously you can name it whatever you like. Then you can replace those click-and-pause blocks of code with clickButtons(true), except the very last one, which would be clickButtons(false).

2) The only difference in those for loops is which member you are taking from data[d]. You can parameterize that easily, too, by referencing that member as a string:

const markAssessment = function(memberName) { 
  for (let d = 0; d < data.length; d++) {
    // Mark Assessment Results
    const personCode = `#DataModel_DataLinks_LearnerAssessments__Data_${d}__Items_RESULT_MARKSOUTOF__Value`
    browser
      .clearValue(personCode)
      .setValue(personCode, data[d][memberName])
      .pause(5000)
  }
}

With both of those, your code would then look like

markAssessment('a1total')
clickButtons(true)
markAssessment('sbatotal')
clickButtons(true)
markAssessment('practicalstotal')
clickButtons(true)
markAssessment('a2total')
clickButtons(false)

You could also put a call to clickButtons inside markAssessment, adding clickNext as a 2nd arg to markAssessment. From there, you could store the memberNames in an array and use memberNameArray.forEach to do most of the heavy lifting for you, depending on your needs, but that's only getting rid of a few extra lines at this point.

Micah L-C
  • 104
  • 1
  • 10