Open braughtg opened 5 months ago
TeamNO has got this one :)
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
@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.
@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.
@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 :)
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:
Any suggestions are appreciated.
Sincerely, Ryan Mueller
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.
@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 get
calls). 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?
@MuellerrAtDickinsonDotedu
Something interesting to note, I had to have separate
its
for editing the database (using the save button) and checking the database (using thewrap
andget
calls). If they were in the sameit
, 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 it
s are run in the same order. While the it
s 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.
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:
setDB sample
in a Terminal in the development environment.Resources:
farmdat2/farmdata2_modules/fd2_example/dbtest
.Additional Information:
Some additional notes relevant to this issue:
.spec.js
file containing your test should be stored in an appropriate location and have a short but descriptive name. Use the locations and an naming from the "Good First issues" as examples..spec.js
file should include a comment at the top that describes what the file as a whole is testing.describe
should describe in a short phrase what the file is testing.beforeEach
method should callcy.waitForPage()
. This will ensure that the page is fully loaded (e.g. that all theMaps
used by the page are loaded) before performing any tests.it
for each of the things to be tested.it
s so that eachit
tests a cohesive set of things.it
should describe in a short phrase what theit
is testing..spec.js
files in thefarmdata2/farmdata2_modules/fd2_example/
sub-tabs (e.g.ui
,api
) may provide some helpful examples.docker/sampleDB/README.md
file.