I am trying to preserve the Session cookie through multiple tests in cypress but Cypress.Cookie.preserveOnce() is not working - reactjs

Am I implementing this functionality wrong or am i missing something?? I watch the application tab of the developer tools, the cookie appears after the setToken() method but despite the Cypress.Cookies.preserveOnce('token_name') in the before each hook. The token is still erased in between tests.
before(() => {
cy.setToken()
})
beforeEach(() => {
Cypress.Cookies.preserveOnce("token_name")
cy.visit(urlPrefix + 'applications').wait(beforeEachWait)
})
after(() => {
cy.clearCookies()
})
it('Form should have title', () => {
cy.contains('Edit Application').should('be.visible')
})
it('The Save button should be disabled until changes have been made', () => {
cy.get('[data-cy=saveBtn]').should('be.disabled')
cy.get('[data-cy=applicationName] input').type(' edited')
cy.get('[data-cy=saveBtn]').should('be.enabled')
})
it('The cancel button redirects to the list view', () => {
cy.get('[data-cy=cancelBtn]')
.click()
.wait(500)
cy.url().then(url => {
const applicationsTitle = url.split('#/')[1]
expect(applicationsTitle).to.equal('applications')
})
})
it('should have delete button in edit mode', () => {
cy.get('[data-cy=deleteBtn]').should('be.visible')
})
})

use this one
Cypress.Cookies.defaults({
preserve: 'session_id',
})
it will work or
before("cookies",() => {
cy.setCookie('session_name', 'value')
}

cypress latest version 10.8.0 no need to add setCookie. Add expermentalSessionAndOrigin and chromeWebSecurity in cypress.config.ts file
e2e: {
baseUrl: "xxxxxxxxxxxxxxxxxxx",
experimentalSessionAndOrigin: true,
chromeWebSecurity: false,
}

Related

How to login with Microsoft SSO in Cypress test when getting cookies blocked error

I'm trying to login to microsoft SSO account in my cypress test and I'm getting "Your browser is currently set to block cookies." error. I am using Cypress version 10+. I've seen posts about using Cypress.Cookies.preserveOnce() but it is deprecated in the 10+ version. This is the error I'm seeing in my cypress test:
This is how I'm trying to login.
cy.session(args, () => {
cy.origin(`https://login.microsoftonline.com/`, {args}, ({ email, password}) => {
cy.visit('/')
cy.get('[name="loginfmt"]').type(email);
cy.get('[name="passwd"]').type(password);
cy.get('[type="submit"]').type('{enter}');
})
});
Any help will be appreciated!
// cypress.config.js
experimentalSessionAndOrigin: true,
pageLoadTimeout: 180000,
experimentalModifyObstructiveThirdPartyCode: true,
chromeWebSecurity: false,
experimentalInteractiveRunEvents: true,
// commands.js
Cypress.Commands.add("jwtlogin", (name, password, token, path) => {
const args = {
name,
password,
token,
path
}
cy.visit(Cypress.config('apiLoginURL'))
cy.on('uncaught:exception', (err, runnable) => {
return false
})
cy.wait(7000)
cy.get('.microsoft').click()
cy.origin('https://login.microsoftonline.com', {
args
}, ({
name,
password,
token,
path
}) => {
cy.wait(17000)
cy.get('body').then((body) => {
if (body.find('#otherTileText').length > 0) {
cy.contains('Use another account').click()
cy.get('#i0116').type(name)
} else {
cy.get('#i0116').type(name)
}
})
cy.get('#idSIButton9').click()
cy.wait(3000)
cy.get('#i0118').type(password)
cy.contains('Sign in').click()
cy.get('div.tile:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(2)').click()
cy.task("generateOTP", token).then(token => {
cy.get("#idTxtBx_SAOTCC_OTC").type(token);
cy.get('#idSubmit_SAOTCC_Continue').click()
cy.wait(3000)
})
cy.on('uncaught:exception', (err, runnable) => {
return false
})
})
cy.wait(5000)
cy.get('body').then((body1) => {
cy.wait(5000)
if (body1.find('#idBtn_Back').is(":visible")) {
cy.wait(5000)
cy.get('#idBtn_Back').click()
}
cy.wait(16000)
})
})
//hooks file
before(() => {
cy.origin('https://login.microsoftonline.com', () => {
cy.visit('https://login.windows.net/common/oauth2/logout')
})
cy.on('uncaught:exception', (err, runnable) => {
return false
})
cy.jwtlogin('testaccount.com', 'Derersr1', 'dfdfd', 'jeet.txt')
cy.window().then(win => win.sessionStorage.clear());
cy.clearCookies();
cy.clearLocalStorage()
cy.wait(11000)
})
Sometimes when logging into Microsoft SSO in Cypress, the error message that appears is 'Your browser is currently set to block cookies,' even in cases where the actual reason for the error is something else. For instance, my account has been suspended and locked. In Cypress, the error message shows "Your browser is currently set to block cookies," but in my system's browser, it shows a different message.
This can be confusing, so it's important to keep in mind that the error message may not always accurately reflect the issue at hand.

How to change "Request to join" button text to "Join Meeting" in iframe

I'm new to daily-co integration in react js. Can you please suggest how to change
"Request to Join" text to "Join Meeting". Thank in advance.
At present in Iframe all content is coming. Can any one please suggest how to change
the "Request to Join" text to "Join Meeting".
My Observations:
One api is calling at the time of page is loaded:
https://b.daily.co/call-ui/16c545a8520b661e39dc13c62b335ffea4cb3651/locales/en/translation.js
{ ....
"haircheck": {
....
"setup": {
"requestToJoin": "Request to join",
"title": "Are you ready to join?",
}
},
}
//React Class component:
import React from 'react';
import DailyIframe from '#daily-co/daily-js';
import Cookies from 'universal-cookie';
import axios from '../../util/axios';
import util from '../../util/util';
const cookies = new Cookies();
class VideoCallFrame2 extends React.Component {
constructor(props) {
super(props);
this.iframeRef = React.createRef();
this.state = {
authorizationToken: 'Bearer ------------',
roomName: '',
room: null,
token: null,
rooms: [],
roomUrlWithToken: null,
isVideoHidden: false,
joinedObject: null,
status: '',
askedQuestions: [],
};
}
componentDidMount() {
this.daily = DailyIframe.wrap(
this.iframeRef.current,
{
showLeaveButton: true,
});
this.setState({
...this.state,
roomUrlWithToken: this.props.meetingRoomUrl
});
this.startRoom();
let temp = this.daily.meetingState();
this.setState({ status: temp });
this.get_candidate_position();
}
get_candidate_position = (e) => {
this.setState({
positionDetails: response.data.candidate[0]
})
}
onHandleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
joinMeetingEvents = () => {
// Meeting related events
this.daily.on('loading', () => { console.log('Loading......') })
this.daily.on('loaded', () => { console.log('Loaded......') })
this.daily.on('joining-meeting', () => { console.log('Joining......') })
this.daily.on('joined-meeting', () => {
console.log('Joined......')
})
this.daily.on('app-message', (e) => {
console.log('app-messageapp-message app-message>>>>>>> ', e)
})
this.daily.on('left-meeting', (e) => {
console.log('Left Meeting......', e)
this.props.history.push('/thankyou')
})
this.daily.on('participant-joined', (e) => {
console.log('Partcipand Joined......', e);
this.setState({
...this.state,
isVideoHidden: true
})
if (this.state.joinedObject.user_id == '') {
}
})
this.daily.on('error', (e) => {
console.log('ERROR......', e)
})
}
leftMeeeting = () => {
this.daily.leave();
this.daily.destroy();
}
startRoom = async () => {
let res = await this.daily.join({
url: this.props.meetingRoomUrl
})
this.setState({
...this.state,
joinedObject: null
})
this.daily.on('loading', () => { console.log('Loading......') })
this.daily.on('loaded', () => { console.log('Loaded......') })
this.daily.on('joining-meeting', () => { console.log('joining-meeting......') })
this.daily.on('joined-meeting', () => {
console.log('Joined meeting......');
})
this.daily.on('joined-meeting', () => {
console.log('Joined meeting......');
})
this.daily.on('meeting-session-updated', () => {
console.log('meeting-session-updated......');
});
this.daily.on('access-state-updated', (evt) => {
console.log('access-state-updated......', evt);
if (evt.access.level == 'lobby') {
//Some code
}
});
this.daily.on('participant-joining', () => { console.log('participant-joining') })
this.daily.on('left-meeting', (e) => {
this.props.history.push('/thankyouPage');
});
this.daily.on("app-message", (e) => {
let Arr = this.state.askedQuestions;
if (
e &&
e.data &&
e.data.message &&
e.data.message.endInterview == "end") {
this.leftMeeeting();
}
});
this.daily.on('participant-joined', (e) => {
console.log('Partcipand Joined......', e);
setTimeout(() => {
this.daily.sendAppMessage({ message: { intervieweraskedQuestions: this.state.askedQuestions } }, '*');
}, 3000)
})
this.daily.on('error', (e) => {
console.log('ERROR......', e)
})
}
render() {
return (
<div className="" style={{ height: '450px' }}>
<iframe className="Video-Frame video-call-frame"
title="video call iframe"
ref={this.iframeRef}
allow="camera; microphone; fullscreen; display-capture"
></iframe>
</div>
)
}
}
export default VideoCallFrame2;
I work at Daily. :) "Request to join" is shown for private rooms with "knocking" enabled. We use this language because clicking the button will alert the room owner to let you in, so you do need to ask to join -- you can't just go straight in.
This can be turned off though. If you make the room public, it will say "Join meeting" instead of "Request to join" because anyone can join. Alternatively, you can make a meeting token for anyone trying to enter a private room so they don't need to ask to join. (In this case, the button text would also be updated to "Join meeting").
More generally, you can't update button text to something custom in the Daily Prebuilt UI, but you can build your on custom UI with our APIs. That's probably too much effort just to update one button, though. :)
I have not used daily.co before but I did a little digging and confirmed my suspicions: As far as I can tell, this is not possible.
In order to for a page to edit the contents of an iFrame, the frame must be on the same origin as its parent page, as per the Same Origin Policy.
Your page is on the origin http://localhost:3001, while the frame is on an origin owned by Daily, e.g. https://server.daily.co.
This policy exists for security reasons, an example is imagine some website https://attacker.com with a frame to https://bankaccount.com, without this policy the attacker could change a button on the frame from "Click to send all money to attacker" to "Click to receive your $1 million reward!"
The only method I have found that may be plausible after doing a couple searches for "origin", "host", etc. on docs.daily.co is this reference page for "Daily's Video Component System (VCS)", but from what I can tell this cannot solve the problem as this only allows you to add an overlay to the video call, not the frame itself.

Problem unit testing a delete method with mock service worker (MSW), node and React

I have MSW setup with React and Typescript, the code works in the browser, ie, it deletes the employee, but not in the test, the other tests are working fine. I'm stumped, there's probably something daft that I'm doing, any help would be greatly appreciated
github repo https://github.com/cherry15/cc2022react
handlers.ts
rest.delete(`${url}/:employeeId`, (req, res, ctx) => {
const { employeeId } = req.params
if (employeeId) {
const employeeIndex = EmployeesData.findIndex(
(employee) => employee.id === employeeId.toString()
)
if (employeeIndex !== -1) {
EmployeesData.splice(employeeIndex, 1)
return res(ctx.status(200))
} else {
return res(ctx.status(404))
}
}
return res(ctx.status(400))
}),
employees.test.tsx
describe('Delete employee', () => {
test('clicking on the OK button deletes the employee', async () => {
renderWithProviders(<EmployeeList />)
await screen.findByRole('heading', { name: /ada lovelace/i })
await screen.findAllByRole('button', { name: 'Delete employee' })
fireEvent.click(screen.getAllByRole('button', { name: 'Delete employee' })[0])
fireEvent.click(await screen.findByText('OK'))
expect(screen.getByText(/ada lovelace/i)).not.toBeInTheDocument()
})
})
This isn't exactly a MSW or RTK Query issue. Being that you're performing async operations, you need to await the disappearance of the target element.
test("clicking on the OK button deletes the employee", async () => {
renderWithProviders(<EmployeeList />);
// Wait for ada lovelace to show up to the party!
await screen.findByRole("heading", { name: /ada lovelace/i });
await screen.findAllByRole("button", { name: "Delete employee" });
fireEvent.click(
screen.getAllByRole("button", { name: "Delete employee" })[0]
);
fireEvent.click(await screen.findByText("OK"));
// Let's wait to make sure she's gone!
await waitForElementToBeRemoved(() =>
screen.queryByRole("heading", { name: /ada lovelace/i })
);
});

Cypress: testing React app in offline mode causes test to hang

I am testing a React application created using create-react-app. I overwrite the App.js file to display text depending on whether the browser is online/offline:
import { Offline, Online } from "react-detect-offline";
function App() {
return (
<div className="App">
<Online>
<p data-testid="online-text">online</p>
</Online>
<Offline>
<p data-testid="offline-text">offline</p>
</Offline>
</div>
);
}
export default App;
I then run npx cypress open and created the following test file:
/// <reference types="cypress" />
const goOffline = () => {
cy.log("**go offline**")
.then(() => {
Cypress.automation("remote:debugger:protocol", {
command: "Network.enable",
});
})
.then(() => {
Cypress.automation("remote:debugger:protocol", {
command: "Network.emulateNetworkConditions",
params: {
offline: true,
latency: -1,
downloadThroughput: -1,
uploadThroughput: -1,
},
});
});
};
const goOnline = () => {
cy.log("**go online**")
.then(() => {
Cypress.automation("remote:debugger:protocol", {
command: "Network.emulateNetworkConditions",
params: {
offline: false,
latency: -1,
downloadThroughput: -1,
uploadThroughput: -1,
},
});
})
.then(() => {
Cypress.automation("remote:debugger:protocol", {
command: "Network.disable",
});
});
};
describe("app", () => {
it("should render online text when online", () => {
goOnline();
cy.get("[data-testid='online-text']").should("exist");
goOnline();
});
it("should render offline text when offline", () => {
goOffline();
cy.get("[data-testid='offline-text']").should("exist");
goOnline();
});
it("should not render online text when offline", () => {
goOffline();
cy.get("[data-testid='online-text']").should("not.exist");
goOnline();
});
});
This tests the app in offline mode according to this guide. The first 2 tests run as expected but the 3rd test gets stuck in an infinite loop:
What Cypress version are you using?
I had a similar issue when after going Offline, Cypress couldn't go Online. After looking for an answer stumbled upon this reason https://github.com/cypress-io/cypress/issues/17723#issuecomment-906152925. Eventually, I was able to get my code working using Cypress version 6.9.1 and not 9.5.1

Make Ant Design Modal Confirm Cancel Button disable immediately after clicking Ok Button

the
confirm({
cancelButtonProps: {
disabled: this.state.processing
},
onOk: () => {
return new Promise((resolve, reject) => {
this.setState({
processing: true
})
})
}
})
doesnt really work cos it doesnt pick the update in the state immediately. It only works after you click on the cancel button and reinitiate the modal confirm.
Instead of relying on the disabled that comes with the
cancelButtonProps
just use this rather
confirm({
cancelButtonProps: {
onClick: () => {
if (this.state.processing) {
alert('You cant cancel, processing still un-going')
} else {
Modal.destroyAll() //use Modal.destroyAll() to destroy the confirm modal
}
}
},
onOk: () => {
return new Promise((resolve, reject) => {
this.setState({
processing: true
})
})
}
})

Resources