I am trying to write a custom command for my app where I create a real user and use its ID in a set of tests.
Since I do test on real BE and DB and I do not stub or mock any data I need to store some values.
The use case is:
I send a request
I get a response with a unique ID
I use this ID in another request and so on...
cy.request('POST', Cypress.env('active') + 'api/players', {})
.then((response) => {
expect(response.status).to.eq(200);
playerID = response.body.id //<-- i need to store is value and use it below
});
cy.request('POST', Cypress.env('active') + 'api/kyc/processes', {
"level": "player",
"player": playerID, //<-- I need to use it here
"venue": 1
});
I have tried aliases and they do not work for this.
Also, I have tried to define variables outside of the test but it is undefined in another request.
The problem is the two cy.request() fire off simultaneously.
Using an additional .then() on the first (nesting the second) ensures sequential execution.
cy.request('POST', Cypress.env('active') + 'api/players', {})
.then((response) => {
expect(response.status).to.eq(200);
playerId = response.body.id
return playerId
})
.then(playerId => {
cy.request('POST', Cypress.env('active') + 'api/kyc/processes', {
"level": "player",
"player": playerId,
"venue": 1
});
});
I had to resort to writeFile and readFile.
It is really dumb but it works.
I dont like it though. I think it should be possible to pass data easier trough few requests.
Related
I am a react-native developer and new to firebase. I am performing firebase realtime database operation, have a look at code below;
firebase.database().ref('events/wedding/items').push(object).then((data) => {
//success callback
dispatch(addPendingInvoice({ ...invoice, id: data.key }))
Alert.alert('Successfully added to Invoices', 'Please go to invoice section to clear first and continue.', [{ text: 'Ok' }])
}).catch((error) => {
//error callback
Alert.alert("Can't book package.", 'Please check your internet connection!', [{ text: 'OK', style: 'destructive' }])
})
Now, I wish to push another object to another node events/wedding/packages right after this firebase database function above. I can use another function inside then callback in above firebase functions. This is not a professional way to do this.
Is there any way to do this?
You can use the update() method to "simultaneously write to specific children of a node without overwriting other child nodes". Note that "simultaneous updates made this way are atomic: either all updates succeed or all updates fails", see the doc.
So in your case you would do along the following lines:
var newNodeKey = firebase.database().ref().child('events/wedding/items').push().key;
var updates = {};
updates['events/wedding/items/' + newNodeKey] = { foo: "bar" };
updates['events/wedding/packages/' + newNodeKey] = { bar: "foo" };
firebase.database().ref().update(updates)
.then(() => {
// The two writes are completed, do whatever you need
// e.g. dispatch(...);
});
All Firebase operations return a promise so you can use Promise.all() to run them all simultaneously.
Promise.all([
firebase.database().ref(reference).set({}),
firebase.database().ref(reference2).set({})
]).then(() => {
console.log("Operations Successful")
}).catch((e) => console.log(e))
You can also push all your operations to an array and then pass that array in Promise.all()
I want to define the response structure of my requests in the simplest way, and the first thing that comes in my mind to do this is a middleware.
My endpoints are returning the response content correctly:
{{base_url}}/users returns a list of users:
{
[
{
"id": 44,
"name": "some name"
[...]
}
]
}
What I want to do (in all requests) is to add the fields status and data (or any other I'd like to add), like this:
{
"status": 200,
"data": [
{
"id": 44,
"name": "some name"
[...]
}
]
}
I've created a middleware that waits for the resolution but I'm not able to get the content nor add some property to it.
[...]
async handle ({request, response}, next) {
await next()
const content = response._lazyBody.content
content.status = response.response.statusCode
}
[...]
I know this will not work but I want something similar to this. I've looked in Adonis docs and forum, but no answers fit to my needs.
Any help will be welcome
You can extend Response By extending the core. The simplest way is to create a file inside start folder and name it hooks.js and copy and paste the content below inside it:
const { hooks } = use('#adonisjs/ignitor')
const Response = use('Adonis/Src/Response')
hooks.after.providersBooted(() => {
Response.macro('customJson', function (status, data) {
this.status(status).json({
status,
data
})
})
})
this piece of code extends the Response module and add customJson method to it which takes two arguments, status and data, and send them back to the client.
And here you can see how to use it:
Route.get('/users', async ({ response }) => {
let status = ''// whatever you want
let data = ''// whatever you want
return response.customJson(status, data)
})
This is the method I'm using, pretty simple.
DailyCountTest: function (){
this.$store.dispatch("DailyCountAction")
let NewPatientTest = this.$store.getters.NewPatientCountGET
console.log(NewPatientTest)
}
The getter gets that data from a simple action that calls a django backend API.
I'm attempting to do some charting with the data so I need to assign them to variables. The only problem is I can't access the variables.
This is what the console looks like
And this is what it looks like expanded.
You can see the contents, but I also see empty brackets. Would anyone know how I could access those values? I've tried a bunch of map.(Object) examples and couldn't get any success with them.
Would anyone have any recommendation on how I can manipulate this array to get the contents?
Thanks!
Here is the Vuex path for the API data
Action:
DailyCountAction ({ commit }) {
axios({
method: "get",
url: "http://127.0.0.1:8000/MonthlyCountByDay/",
auth: {
username: "test",
password: "test"
}
}).then(response => {
commit('DailyCountMutation', response.data)
})
},
Mutation:
DailyCountMutation(state, DailyCount) {
const NewPatientMap = new Map(Object.entries(DailyCount));
NewPatientMap.forEach((value, key) => {
var NewPatientCycle = value['Current_Cycle_Date']
state.DailyCount.push(NewPatientCycle)
});
}
Getter:
NewPatientCountGET : state => {
return state.DailyCount
}
State:
DailyCount: []
This particular description of your problem caught my eye:
The getter gets that data from a simple action that calls a django backend API
That, to me, implies an asynchronous action and you might be getting a race condition. Would you be able to post a sample of your getter function to confirm my suspicion?
If that getter does indeed rely on an action to populate its contents, perhaps something to the effect of the following might do?
DailyCountTest: async () => {
await this.$store.dispatch('DailyCountAction')
await this.$store.dispatch('ActionThatPopulatesNewPatientCount')
let NewPatientTest = this.$store.getters.NewPatientCountGET
// ... do whatever with resulting array
}
You can also try with a computer property. You can import mapGetters
import { mapGetters } from 'vuex'
and later in computed properties:
computed: {
...mapGetters(['NewPatientCountGET'])
}
then you can use your NewPatientCountGET and it will update whenever the value changes in the store. (for example when the api returns a new value)
Hope that makes sense
componentWillMount() {
console.log('Component WILL MOUNT!')
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
let playlists = [];
res.data.data.playList.map((value, key) => playlists.push(new Audio(value.url)));
this.setState((prevState) => {
return { audioList: playlists, categories: res.data.data.playList }
}, () => console.log(this.state.audioList));
}).catch( (err) => {
console.log(err);
});
}
**I also call this in componentDidUpdate() **
The above code that I used in my ReactJS web app to retrieve data from my DB that looks something like:
{
"_id": {
"$oid": "5a2b903abcf92a362080db4f"
},
"name": "test",
"playList": [
{
"url": "https://p.scdn.co/mp3-preview/a3fd5f178b7eb68b9dba4da9711f05a714efc966?cid=ed36a056ee504173a3889b2e55cbd461",
"artist": "Lil Pump",
"songName": "D Rose",
"_id": {
"$oid": "5a2c5631e54ca10eb84a0053"
}
},
{
"url": "https://p.scdn.co/mp3-preview/155643656a12e570e4dda20a9a24d9da765b9ac5?cid=ed36a056ee504173a3889b2e55cbd461",
"artist": "Tee Grizzley",
"songName": "From The D To The A (feat. Lil Yachty)",
"_id": {
"$oid": "5a2c5631e54ca10eb84a0054"
}
}
],
"__v": 0
}
I retrieve the url for each songs and store it inside my state this.state.audioList to make a playable list.
I access each song with an index
So, this.state.audioList[0] would be the first song.
When I try to play this music by doing
this.state.audioList[0].play(), this totally works fine.
The problem is when I try to pause it.
this.state.audioList[0].pause() does not pause the song for some reason.
I am assuming that it is because the this.state.audioList is getting updated every time and the Audio object that I am trying to pause is a new object that has nothing to do with the one currently being played.
Am I right? If so, is there a solution to this issue?
Please help!
That should work in componentWillMount although componentDidMount is preferred, see : https://reactjs.org/docs/react-component.html#componentdidmount
Quoted from this link (remote endpoint being your axios URL here) :
If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
But you're almost certain that won't work if you put your axios.get() request in componentDidUpdate, because this method is called each time your component has been updated and re-rendered.
From the React Component Lifecycle document, you'll see that componentWillMount and componentDidMount both stay in the Mounting section (that is, they are called only once when the components DOM element are inserted in the DOM), whereas componentDidUpdate is in the Updating section, and therefore is called each time your component's state or props are changed (what happens when your axios.get() promise is fulfilled).
Also, as map returns an array, why not assign its returned value to your audioList ? Here is an example that you may want to try (untested though, sorry !):
componentDidMount() {
console.log('Component DID MOUNT!')
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
this.setState({
audioList: res.data.data.playList.map(value => new Audio(value.url)),
categories: res.data.data.playList
});
}).catch( (err) => {
console.log(err);
});
}
Hope this helps!
I'm having some problems on making a request from angular to my Java backend.
My current code is this:
$scope.listdevices=function(){
var devices = $resource('http://localhost:8080/userapi/devices/:userId',{userId:'#userId'});
var list=devices.query({userId:$scope.userId});
console.log(JSON.stringify(list));
console.log(list);
console.log(list.length+"TAMANHO")
};
The data is being being fetched and it looks like this:
But the objects are not being saved in my list when I call listdevices to return a list of objects to iterate.
Thanks a lot
.query will be async, so you need a callback or a promise. Anyway, if you are trying to get a single record, you use "get". Here you have an example:
myApp.factory('Device', function($resource) {
return $resource('http://localhost:8080/userapi/devices/:userId', {
userId: '#userId'
});
});
myApp.controller('YourCtrl', function(Device) {
Device.get({
userId: 1
}).$promise.then(function(res){
console.log(res)
})
})
.query is for query your endpoint, for example if you wanted to search devices with conditions. Resource assumes that 'http://localhost:8080/userapi/devices' will return an array, while /:userId will return an object.
Extending the answer as per your comment, if you wanted to query a list of devices of a certain users (which returns an array), you would indeed use .query
Device.query({
userId: 1
}).$promise.then(function(results) {
console.log(results)
})
Alternatively, if you use a callback you have access to the headers.
Device.query({
userId: 1
}, function(results, headers) {
})