DickinsonCollege / FD2School-FarmData2

Other
0 stars 25 forks source link

Seeding Report: Test Cancel Seeding Log Edit #40

Open braughtg opened 5 months ago

braughtg commented 5 months ago

The Seeding Report allows the values within a seeding log (i.e. a row) to be edited by clicking the “Edit” button (i.e. the blue pencil button). When a row is being edited the “Edit” button changes to two buttons. The “Save” button (the green check mark) will save the changes to the database. The “Cancel” button (the brown X) discards any edits and does not change the database.

Notes:

Resources:

Additional Information:

Some additional notes relevant to this issue:


Original issue by braughtg Tuesday Apr 11, 2023 at 04:39 GMT

MuellerrAtDickinsonDotedu commented 2 months ago

TeamNO has got this one :)

megantriplett commented 2 months ago

Hello @braughtg @wpgoble , We are working on this issue and are confused about how to apply our knowledge of accessing the FarmOSAPI in HTML to accessing the API in a Cypress test. We understand that we shouldn't use the Seeding Report to check a change in the database, but we are not sure how to access the database otherwise, because we are used to accessing the database in a Vue method.

Thanks, Megan, Chloe @cschnydman, Ryan @MuellerrAtDickinsonDotedu

wpgoble commented 2 months ago

@megantriplett I believe you can write a cypress test which uses an async call to connect to the database. In that case you can ping the database for results and see if things changed. Since you are working on FarmOS you might be able to pull their API commands in order to grab the pages that are printed to the table, and then test to see if there is a difference. Check out this link for connecting a cypress test to a database.

braughtg commented 2 months ago

@megantriplett @wpgoble For these tests I think that farmdata2/farmdata2_modules/fd2_example/api/api.modify.spec.js provides some useful examples of how to access and modify the database from within a test.

cschnydman commented 2 months ago

@wpgoble Thank you for responding to our comment so swiftly! We read through the link that you sent us. The link says to us SQL and other elements that were not discussed in our class. Therefore, we are not sure how to implement what it is suggesting. But thank you anyway for trying :)

MuellerrAtDickinsonDotedu commented 2 months ago

Looking over the api.modify.spec.js code, it looks like the way to interact with the OSAPI is done through the .wrap() function. I have tried to emulate the example code using the getRecord api method, but it fails.

This is the section of code that fails:

var FarmOSAPI = require('../../resources/FarmOSAPI.js')
var getRecord = FarmOSAPI.getRecord

describe("Testing cancel and submit button for table element in seeding report", () => {
    let endpoint = "/log.json?id=229"
    //let allpages = null

    beforeEach(() => {
        cy.login("manager1", "farmdata2")

        cy.visit("farm/fd2-barn-kit/seedingReport")

        cy.wrap(getRecord(endpoint)).as('fetch')

        cy.get('@fetch').then((response) => {
            expect(response.status).to.equal(200)  // 200 - OK/success
            expect(response.data.list[0].notes.value).should('contain text','')
        })
        ...

This is the error I get:

Screenshot 2024-04-26 at 2 04 38 PM

Any suggestions are appreciated.

Sincerely, Ryan Mueller

braughtg commented 2 months ago

Your cy.wrap(...).as('fetch') and cy.get('@fetch') should be in a test (i.e. in an it) rather than in the beforeEach, which runs before every it. The beforeEach is also missing the cy.waitForPage() which is a critical piece.

MuellerrAtDickinsonDotedu commented 1 month ago

@broughtg Thanks for the advice, we should have a pull request sent out soon. Having the .wrap() and .get() calls inside of the its worked. Something interesting to note, I had to have separate its for editing the database (using the save button) and checking the database (using the wrap and getcalls). If they were in the same it, the wrap and get calls didn't have the changes made by hitting the save button. I have some examples bellow.

This didn't work:

it("Make an edit, submit, and check that database was changed", () => { 
        cy.get('[data-cy=r0-edit-button]').click({force: true})
        cy.get('[data-cy=td-r0c13]').type('edit:)')
        cy.get('[data-cy=r0-save-button]').click({force: true})

        cy.wrap(getRecord(endpoint)).as('fetch')
        cy.get('@fetch').then((response) => {
            expect(response.status).to.equal(200)  // 200 - OK/success
            expect(response.data.list[0].notes.value).to.have.string('edit:)')
        }) //.data.list[0].notes.value
    })

But this did:

it("Make an edit and submit", () => { 

        cy.get('[data-cy=r0-edit-button]').click({force: true})
        cy.get('[data-cy=td-r0c13]').type('edit:)')
        cy.get('[data-cy=r0-save-button]').click({force: true})

    })

    it("Check that database was changed", () => {
        cy.wrap(getRecord(endpoint)).as('fetch')
        cy.get('@fetch').then((response) => {
            expect(response.status).to.equal(200)  // 200 - OK/success
            expect(response.data.list[0].notes.value).to.have.string('edit:)')
        })
    })

Do you know why this is?

braughtg commented 1 month ago

@MuellerrAtDickinsonDotedu

Something interesting to note, I had to have separate its for editing the database (using the save button) and checking the database (using the wrap and getcalls). If they were in the same it, the wrap and get calls didn't have the changes made by hitting the save button.

When the click on save and the call to getRecord are in the same it, the way that you have it, I suspect that the getRecord is being executed before the submit completes. So getRecord does not find the edit, because it is not yet in the database. This is a little counter intuitive, but it occurs because the cy.wrap function is executed asynchronously and thus can occur before the save completes.

The solution of splitting this into two it blocks will work as long as the its are run in the same order. While the its seem to typically be executed in the order they appear in the file, it is technically not guaranteed.

A more complete solution would use an intercept to check that the API call caused by the save has completed before going on to the getRecord. You can find an example of how this works in the Click Update Asset again, and check that crop is toggled back to SPINACH in db. test in the api.modify.spec.js file. That example is slightly different but between it and a little reading about cy.intercept and I think you'll be able to figure it out.