Cypress: cannot find button in toolbar - cypress

I just started playing with cypress and I am trying to write down some tests in my sandbox application. In my first test user should click on a 'button' to make the toolbar to appear, then click on a button to activate the feature, then click a couple of times on a leaflet map to draw a line.
As you can see: click on 'Tools', then click on 'draw route' button and then click on map to draw.
This dummy app is wrapped inside a web component, here is the code:
And here is my test code:
describe('Draw geometries on map', ()=>{
beforeEach(() => {
cy.visit('http://192.168.49.2:30000/scouter/');
})
...
it('can draw after clicking draw button', ()=>{
cy.get('scouter-web').shadow().find('.scouter-tools-main-button').click()
cy.get('scouter-web').shadow().find('draw route').click()
console.log('new cy')
cy.get('scouter-web').shadow().get('scouter-web').shadow().find('#map')
.click(400, 400)
.click(400, 600)
.click(500, 600)
})
});
Problem is I, after clicking 'Tools', I can't 'find' the 'draw route' button. What am I missing? The whole stuff can be found here, subproject is scouter-web.

Instead of using the shadow() repeatedly, you can mention includeShadowDom: true once in your cypress.json file.
With find you can just use selector but I think you are using text. If you just want to use text, you can use contains.
cy.contains('draw route').click()
And if your application is throwing Uncaught Exceptions you can add to your cypress/support/index.js to globally turn off all uncaught exception handling. But a fair bit of warning, do this only when you are sure that the exceptions generated can be ignored.
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})

Related

Cypress E2E testing: How to test the text message on toast container (or) popup on a web page?

screenshot of html code for the error toast popupI am trying to get the element of popup (or) toast-container and asserting the text, but I am getting an error that element never found. Please someone help?
describe('Wholesoft Login Page', function(){
it('Check Login popup', function(){
cy.visit('https://https://platform.wholesoftmarket.com/login')
cy.get('#email').type('kj#gmail.com')
cy.get('#password').type('hello')
cy.get('button.btn.active').click()
cy.get('div').within(($div)=>{
cy.get('div.overlay-container').should('have.text','no record found')
})
})
})
You need to set a bigger timeout for the element, waiting to be present in the DOM:
cy.get('div[aria-label="Error"]', {timeout: 10000}).should('have.text','no record found')
// maybe you can use the class selector on that div (div.toast-title.ng-star-inserted)
// default timeout is 6000
// increase it until it is caught by Cypress
You need to wait till the toast or pop-up element is visible to access it for further steps.
Please make sure element selector is right.
following cmd
cy.get('div.overlay-container').should('be.visible').should('have.text','no record found')

How to Unmount a screen when moving to another in React Native

I'm developing a React Native app using React Navigation v4, React Hooks and ES6.
I have 2 bottom tabs (Movies, Shows) and 4 screens with the following Stack structure:
**Movies**
-- MovieList
-- MovieDetail
**Shows**
-- ShowList
-- ShowDetail
My scenario
1) Moving from Movie list to an individual movie page
MovieList contains a list of movies, when I click on one of them, I first fetch some API data then move to the MovieDetail screen like this
dispatch(apiFetchActions.fetchMovies(movieId)).then((response) => {
props.navigation.navigate({
routeName: "MovieDetail",
params: {
assetId: movieId,
assetName: movieTitle,
},
});
MovieDetail is now on top of the Movies stack and MovieList at the bottom
2) Moving to a different tab (navigation stack)
I then click on Shows (2nd Tab) which takes me to the ShowList using props.navigation.navigate('ShowList')
3) The problem
If I click on the Movies Tab, I expect to be moved back to MovieList but since MovieDetail was never unmounted, it is still at the top of the Movies stack meaning that I see an old screen. I have to click twice to go back to the MovieList screen.
I've read quite a few suggestions on how to use onFocus/onBlur subscription however I could not found a solution using React Hooks.
My ideal solution would be to find a way to listen to the onBlur status in MovieDetail screen possibly using useEffect hook and somehow unmount it before leaving.
I found a way to make it easier to always move to the initial top of the stack when you click on any bottom tab icons.
You simply need to add the on Press and the screen reference like this
Stars: {
screen: StarsNavigator,
navigationOptions: ({ navigation }) => ({
tabBarIcon: (tabInfo) => {
return (
<Ionicons name="ios-people" size={22} color={tabInfo.tintColor} />
);
},
tabBarLabel: Platform.OS === "android" ? <Text>Stars</Text> : "Stars",
tabBarOnPress: () => {
navigation.navigate("StarsList");
},
}),
},
Star is one of my screens in BottomTabNavigator and using navigation.navigate("You Screen") does the trick. So regardless in which level of the stack you find yourself, every time you click on the Star tab you always end up to the original top level.

Hide Testcafe Overlay

I'm trying to use testcafe to fill forms on a page.
When the form is filled, I'd like to be able to stop the test with the window still open so a human can review the form before clicking submit.
I can pause the test with t.debug() but this locks the page and shows the testcafe controls overlay at the bottom.
Is there a way I can remove this overlay and unlock the page?
I've tried using client functions to hide the element with javascript as follows:
test('test_1', async (t) => {
const hideOverlay = ClientFunction(function() {
const target = document.querySelector('#root-hammerhead-shadow-ui > div > div');
target.style.display = 'none';
return true;
})
await t.wait(5000);
setTimeout(async function() {
const res = await hideOverlay();
console.log('-------->', { res });
}, 6000);
await t.debug();
});
Since no code will be executed after debug is invoked, I thought I could use a settimeout to queue the call to the function that hides the overlay, so that it is queued and only executes after debug is called and the overlay is visible.
Didn't work though :( code didn't execute, got an unhandled promise rejection.
Could really use some help here, thanks :)
Yes, you can unlock the page by clicking the 'Unlock page' button in the footer as #VysakhMohan mentioned in the comment.
Please refer to the client-side debugging documentation for more details.

Protractor : Check pdf document in a new tab

I am trying to automate a scenario where I click on a button and its opens up a pdf document in new tab. When the test fails, a json object is displayed instead of the pdf document.
I use this code :
element(by.id('MyButton')).click().then(function () {
browser.getAllWindowHandles().then(function (handles) {
newWindowHandle = handles[1]; // this is your new window
browser.switchTo().window(newWindowHandle).then(function () {
var EC = protractor.ExpectedConditions;
// Waits for the element is not present on the dom.
browser.wait(EC.stalenessOf($('#formattedJson')), 5000);
});
});
});
I can open the new tab but when I dont know how to check the content (pdf or json object).
Some advices would be appreciated.
For instance I have the error :
Failed: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
Thanks in advance.
;-)
Probably because the window that is rendering your pdf isn't an angular page. You can tell protractor not to wait for angular by using browser.waitForAngularEnabled(false). You should do this right before your call to switch window. Just remember to turn it back on when you close the window and switch back to your main app window. Check out this documentation for more info.
browser.getAllWindowHandles().then(function (handles) {
newWindowHandle = handles[1]; // this is your new window
browser.waitForAngularEnabled(false); //add this and it should work
browser.switchTo().window(newWindowHandle).then(function () {
var EC = protractor.ExpectedConditions;
// Waits for the element is not present on the dom.
browser.wait(EC.stalenessOf($('#formattedJson')), 5000);
});
}):

Slickgrid - Lost focus to end edit

When editing my grid, if I click outside the grid, the box I was editing is still editable. How do I get the edited cell to "complete" the edit when it looses focus?
The following code will save the current edit.
Slick.GlobalEditorLock.commitCurrentEdit();
You'll need to place this inside an event handler that you think should trigger the save. For example, if you're using the sample text editor plugin, I believe an editor-text CSS class is added to the input field that's created when you're editing a cell so something like this should work:
$('#myGrid').on('blur', 'input.editor-text', function() {
Slick.GlobalEditorLock.commitCurrentEdit();
});
I found that I needed to wrap clav's handler in a timeout:
$("#myGrid").on('blur', 'input.editor-text', function() {
window.setTimeout(function() {
if (Slick.GlobalEditorLock.isActive())
Slick.GlobalEditorLock.commitCurrentEdit();
});
});
to avoid errors like:
Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist.
when using the keyboard to navigate. Presumably the new blur handler fires before SlickGrid can do its own handling and this causes problems.
Unfortunately, probably due to differences in event processing, Grame's version breaks keyboard navigation in chrome.
To fix this, I added another check to only commit the edit, if the newly focused element is not another editor element within the grid (as the result of keyboard navigation):
$('#grid').on('blur.editorFocusLost', 'input.editor-text', function() {
window.setTimeout(function() {
var focusedEditor = $("#grid :focus");
if (focusedEditor.length == 0 && Slick.GlobalEditorLock.isActive()) {
Slick.GlobalEditorLock.commitCurrentEdit();
}
});
});
This seems to work in current versions of firefox, chrome and ie.

Resources