Compare two Session ID's in Cypress - javascript

I am new to automation and coding in general and I would like to compare two session ID values with the following steps:
Get first value right after logging in
Refresh page
Get second value and make an assertion.
I made a custom command in order to simplify things:
Cypress.Commands.add('getSessionId', () => {
let sessionId
cy.getCookie('development')
.its('value').then(($value) => {
sessionId = String($value)
})
})
I want the test script to look something like this:
let firstSessionId = cy.getSessionId()
cy.reload()
let secondSessionId = cy.getSessionId()
expect(firstSessionId).to.eq(secondSessionId)
There are two problems with this:
I cannot access the values as strings in this scenario
The expect runs before getting the ID's (i guess because of the asyncronous nature of cypress?)
I would appreciate any hint what I do wrong. Thanks

This is the simplest way to perform the test, no need for a custom command in this case.
cy.getCookie('development').its('value')
.then(sessionId1 => {
cy.reload()
cy.getCookie('development').its('value')
.then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})
If you want a custom command for other reasons,
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development').its('value') // last command is returned
})
cy.getSessionId().then(sessionId1 => {
cy.reload()
cy.getSessionId().then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})

You can return the value from the custom command like this:
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development')
.its('value')
.then((val) => {
return cy.wrap(val)
})
})
Then in your test, you can do this:
//Get First session Id
cy.getSessionId.then((sessionId1) => {
cy.wrap(sessionId1).as('sessionId1')
})
//Refresh Page
cy.reload()
//Get Second session Id
cy.getSessionId.then((sessionId2) => {
cy.wrap(sessionId2).as('sessionId2')
})
//Assert both
cy.get('#sessionId1').then((sessionId1) => {
cy.get('#sessionId2').then((sessionId2) => {
expect(sessionId1).to.eq(sessionId2)
})
})

Related

Web-Bluetooth API, can not update characteristics. time-dependent updating possible?

I try to get the characteristics everytime they change, the problem is, they change but the eventListener doesn't recognize it. So i only get the first value, after connecting to my BLE, but nothing happen after that. Is there something wrong in my code ?
Another Question, is there a way to update the characteristic every, i dont know 5 Seconds for example? And how would you do that, are there any code examples?(Maybe with setInterval() ? )
Thank you !
function test() {
console.log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['af07ecb8-e525-f189-9043-0f9c532a02c7']
}) //c7022a53-9c0f-4390-89f1-25e5b8ec07af
.then(device => {
console.log('Gatt Server Verbindung');
return device.gatt.connect();
})
.then(server => {
console.log('Dose Service...');
return server.getPrimaryService('af07ecb8-e525-f189-9043-0f9c532a02c7');
})
.then(service => {
console.log('mgyh Characteristic...');
return service.getCharacteristic('a99e0be6-f705-f59c-f248-230f7d55c3c1');
})
.then(characteristic => {
// Set up event listener for when characteristic value changes.
characteristic.addEventListener('characteristicvaluechanged',dosechanged);
return characteristic.readValue();
})
.catch(error => {
console.log('Das geht nicht: ' + error);
});
}
function dosechanged(event) {
let dose = event.target.value.getUint8(0)+event.target.value.getUint8(1)*10+event.target.value.getUint8(2)*100 + event.target.value.getUint8(3)*1000+ event.target.value.getUint8(4)*10000;
console.log('Received ' + dose);
}
You missed a characteristic.startNotifications() call to start receive notification. example
setInterval would be fine to call readValue() every 5 seconds.

How to populate multiple prompts in a row in Cypress before initial page load

Cypress newbie here.
I'm trying to populate data into 3 different prompts that appear before the page loads completely. These values are then added into session storage. It is my understanding that since the site is not fully loaded I can't chain off cy.visit() so I've been using the onBeforeLoad so I can populate the data for these prompts:
before(function() {
cy.visit(base_url, {
onBeforeLoad(win) {
cy.stub(win, 'prompt').returns('someString').as('stub1')
cy.stub(win, 'prompt').returns('someOtherString').as('stub2')
cy.stub(win, 'prompt').returns('anotherString').as('stub3')
}
})
})
The issue is that when I look under "Spies/Stubs" I only see the stub1 being used 3 times as opposed to 3 different stubs being used once.
I also get the error
TypeError: Attempted to wrap prompt which is already wrapped
Any help will be highly appreciated.
Thank you all in advance.
EDIT:
Doing something like
before(function() {
cy.visit(base_url, {
onBeforeLoad(win) {
demo_site_info.forEach(element => {
cy.stub(win, 'prompt').callsFake(() => {
return element
})
});
}
})
})
yields a TypeError:
Attempted to wrap prompt which is already wrapped
Using callsFake(fn) allows multiple fake values.
it('fakes return values multiple times', () => {
const mod = {
doit: () => 'done'
}
let call = 0
const fakes = ['done1', 'done2', 'done3']
cy.stub(mod, 'doit').callsFake(() => {
return fakes[call++]
})
console.log(mod.doit()) // done1
console.log(mod.doit()) // done2
console.log(mod.doit()) // done3
console.log(mod.doit()) // undefiend
})

Test not looping in protractor

I have a test that I'm trying to fix. It needs to click on each result and verify the price and name match from the initial result with the final individual result. Currently my code will click on only the first image but will not navigate back to the results page to try the next result. I tried to remove the first() as my understanding is that method only takes the very first element and ignores the rest. Sadly that didn't work. What am I missing?
tester.it('links to the correct product details page when a result is clicked', () => {
const $offer = element.all(by.css('#main-results .catalog-offer')).first();
const offerResultsText = [];
let offerResultsPrice;
return Promise.all([
$offer.all(by.css('.offer-name .name-part')).map(($namePart) =>
$namePart.getText().then((partText) => offerResultsText.push(partText))
),
$offer
.element(by.css('.price'))
.getText()
.then((offerPrice) => (offerResultsPrice = offerPrice)),
])
.then($offer.element(by.tagName('a')).click)
.then(() =>
browser.wait(
protractor.ExpectedConditions.presenceOf(
element(by.css('#recently-purchased-details'))
),
5000
)
)
.then(() =>
expect(element(by.css('.details .subtotal > span')).getText()).to.eventually.equal(
offerResultsPrice
)
)
.then(() => {
return offerResultsText.map((sourceString) => {
console.log(sourceString);
return expect(
element(by.css('.details .setting .info')).getText()
).to.eventually.contains(sourceString);
});
});
});
Figured out what I was doing wrong. I needed to remove the return and then use our internal method afterward to loop through the results urls. Looked like this in the end...
expect(testerUtils.getPageId()).to.eventually.equal('Recently Purchased Engagement Ring Details');
testerUtils.go(testContext.url);

Vue delete current data values after #changed from select box

I have a query that gets a record and display it to a graph. I can already display the records but when I click a record without a result and then click the previous with a result. The data property in vue adds the current result resulting to append the previous one. What I want is when I select another option from the select tag, the current data will be deleted and will be replaced with the current result with the new one.
Here is my Graph
When i clicked Vince from the select box I got the exact data and the graph. here is my Vue devtools details
But when I click mark the second teacher which has NO data or result
the data from my previous array is still in there and when I click back to vince which has a data in it here is the result
and the graph is like this
My code right now is which is not working
getdata() {
let self = this
axios.get('/getGraph/' + self.teacher)
.then(({
data
}) => {
if(data.length > 0){
data.splice()
}
else{
data.date.forEach(x => {
self.dataSource.data.push(x);
});
}
})
}
My original code is this
getdata() {
let self = this
axios.get('/getGraph/' + self.teacher)
.then(({
data
}) => {
data.date.forEach(x => {
self.dataSource.data.push(x);
});
})
},
getTeachers() {
axios.get('getTeachers')
.then((res) => {
this.teachers = res.data
})
.catch((e) => {
console.log(e)
})
}
Could someone tell me what is wrong and how could I achieve what i want to do? Thanks a lot.
You have to clear your data everty time you recieved data from the server like this one.
axios.get('/getGraph/' + self.teacher)
then(({
data
}) => {
self.dataSource.data = []
data.date.forEach(x => {
self.dataSource.data.push(x);
});
})

How do I convert each line elements into an Array, So I can select only one element like data[2]

here is my code, I have received data from firebase storage.
listRef.listAll().then((res) => {
res.prefixes.forEach((folderRef) => {
// All the prefixes under listRef.
// You may call listAll() recursively on them.
});
res.items.forEach((itemRef, index) => {
itemRef.getDownloadURL().then((url) => {
console.log(`${index} ${url}`)
})
});
})
Here is my output result like
0 https://myfirebaseapp.com/videos/nice.mp4
1 https://myfirebaseapp.com/videos/bad.mp4
2 https://myfirebaseapp.com/videos/funny.mp4 [ I want only this element instead of whole list ]
3 https://myfirebaseapp.com/videos/good.mp4
4 https://myfirebaseapp.com/videos/sad.mp4
You can use the find() method on your array. Here's an example:
var items = [
'https://myfirebaseapp.com/videos/nice.mp4',
'https://myfirebaseapp.com/videos/bad.mp4',
'https://myfirebaseapp.com/videos/funny.mp4',
'https://myfirebaseapp.com/videos/good.mp4',
'https://myfirebaseapp.com/videos/sad.mp4'
]
var funny = items.find(x => x.endsWith('funny.mp4'));
console.log(funny);
For your code, it might look something like this:
listRef.listAll().then((res) => {
...
// Find the string that ends with 'funny.mp4'.
var funnyItem = res.items.find(x => x.fullPath.endsWith('funny.mp4'));
if(funnyItem) {
// The item we want was found. Do something with it...
funnyItem.getDownloadURL().then((url) => {
console.log(`Fetching ${url}...`);
});
}
})
The above example will work if we don't know the location of funny.mp4. If you know for sure that the location of the item you want is always going to be 2, then you could get away with doing this:
listRef.listAll().then((res) => {
...
res.items[2].getDownloadURL().then((url) => {
console.log(`Fetching ${url}...`);
});
})
If you really just need a collection of the download URLs (hard to tell from your question), then you can project your items array with the map function like this:
listRef.listAll().then(async (res) => {
...
var urls = await res.items.map(async x => Promise.all(await x.getDownloadURL()));
console.log(`Fetching ${urls[2]}...`);
})
Keep in mind that this will invoke the awaitable getDownloadURL() method on every item, which is probably undesired.
You should put an if statement inside the forEach, checking on the index (if you generically want the 3rd element of the list) or on the name of the video (if you want specifically that video)

Categories