I have 3 sites, and each site has 3 envs, each with their config.json and fixtures.json. However, part of the fixture is common, like routes which contains endpoints. Following the DRY pattern, I refactored the common bits to a routes.json.

I basically want to load multiple fixtures...
before()), unlike this exampleIdeally I would be able to access each fixture file independently like:
cy.visit(routes.account.edit)
...
cy.get(selectorNotification).should("contain", keywords.dialog.success)
Given a file like:
// routes.json
{
"account": {
"edit": "/account/edit"
},
"users": {
"list": "/users",
"search": "/user/search"
},
...
}
I've tried a mix of cy.fixture, Cypress.config, fs.readFile, cy.readFile to no avail and now I'm too biased to think out of the box.
Please, can you advise me a solution? I feel like I'm over-engineering it.
This works:
const configHelper = new ConfigHelper()
let routes, keywords, fixtures
before(() => {
cy.fixture(configHelper.getRoutesPath()).then(c => {
routes = c
})
cy.fixture(configHelper.getKeywordsPath()).then(c => {
keywords = c
})
cy.fixture(configHelper.getFixturesPath()).then(c => {
fixtures = c
})
})
describe("Example component under test", function() {
it("expects a certain behaviour", function() {
expect(routes).to.be.not.undefined
expect(keywords).to.be.not.undefined
expect(fixtures).to.be.not.undefined
})
})
But it's annoying having to copy that whole block of boilerplate to every test file.
Why can't you use this solution (load once, add to test context before each) https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/fundamentals__fixtures/cypress/integration/load-fixtures-spec.js#L100
Or even better, if you use JSON fixtures just require them from the spec, they will be bundled, see https://github.com/cypress-io/cypress-example-recipes/commit/949c65adbd8fb38a4c23012b1625db6f160d6420
Thanks for replying ;)
_This solution (load once, add to test context before each)_
That's what I'm doing in my comment above. It loads the fixtures once per test file, ie. 10x test files -> 10x load fixtures. What I wanted was to load once per cypress execution, ie. 10x test files -> 1x load fixtures.
wow, that works? 😮 const city = require('../site/env/routes.json') that's it?
My only problem is that the path is dynamic based on 2 env vars. So it would look like `const routes =
require(`../config/${Cypress.env("REALM")}/routes.json`)
Edit: It's impossible to have dynamic imports.
Any other idea?
I think this is a reasonable use case, having multiple envs and sites/translations of the same site.
Well require should work, also you can load them once using before and just attach to Cypress object and they will stay there. I would not do this though because it makes things magical and unclear and harder to debug later for someone who is not familiar with this trick later
Sent from my iPhone
On Jun 18, 2019, at 10:34, Diogo Nunes notifications@github.com wrote:
Thanks for replying ;)
This solution (load once, add to test context before each)
That's what I'm doing in my comment above. It loads the fixtures once per test file, ie. 10x test files -> 10x load fixtures. What I wanted was to load once per cypress execution, ie. 10x test files -> 1x load fixtures.
if you use JSON fixtures just require them from the spec
wow, that works? 😮 const city = require('../site/env/routes.json') that's it?
My only problem is that the path is dynamic based on 2 env vars. So it would look like `const routes =require(
../config/${Cypress.env("REALM")}/routes.json)
Edit: It's impossible to have dynamic imports.Any other idea?
I think this is a reasonable use case, having multiple envs and sites/translations of the same site.—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
Sorry for the dumb question, but how do you "attach to the Cypress object"?
Cypress.myFixture = require(“path/to/fixture/files”)
Sent from my iPhone
On Jun 21, 2019, at 11:19, Diogo Nunes notifications@github.com wrote:
Sorry for the dumb question, but how do you "attach to the Cypress object"?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
Doesn't work: Error: Cannot find module 'cypress/config/imovirtualpt/routes.json'
before(() => {
const routesPath = ConfigHelper.getRoutesPath()
Cypress.routes = require("cypress/config/" + routesPath)
})
describe("Example component under test", function() {
it("expects a certain behaviour", function() {
expect(Cypress.routes).to.be.not.undefined
})
})
I guess I'll have to settle with the solution at https://github.com/cypress-io/cypress/issues/4483#issuecomment-503014007
Another solution could be to collect fixtures in a Promise
The paths parameter is an array of paths to fixtures
const fixtures = (paths) => Promise.all(paths.map(p => cy.fixture(p)))
Use like this:
fixtures(['path/1', 'path/2']).then(filesContents => {
console.log(filesContents)
})
Another solution could be to collect fixtures in a Promise
The paths parameter is an array of paths to fixturesconst fixtures = (paths) => Promise.all(paths.map(p => cy.fixture(p)))Use like this:
fixtures(['path/1', 'path/2']).then(filesContents => { console.log(filesContents) })
Thank you so much for this!
I managed to build a multi-upload command based on this input, which takes an array of fixture-paths and names and upload multiple files in a single array.
In case anyone needs it:
```js
Cypress.Commands.add('uploadMultiple', ({localPaths = [], fileNames = [], mimeType = 'image/png'}) => {
const fixtures = (paths) => Promise.all(paths.map(p => cy.fixture(p)))
const encoding = 'base64'
fixtures(localPaths).then(filesContents => {
const payload = fileNames.map((fileName, i) => (
{
fileContent: filesContents[i],
fileName,
encoding,
mimeType
}))
cy.get('input[multiple]')
.upload(payload)
})
})
```
Next step is to determine the right MimeType based on the fileName extension, but that should not be too difficult.
@deventually @IMightGitIt running Promise.all on cy.fixture doesn't seem to work for me. Is there anything else expected but not mentioned in this piece of code?
Most helpful comment
This works:
But it's annoying having to copy that whole block of boilerplate to every test file.