I have several Detox test files/suites that are separated into test suites for various high level app features. We have Detox set up with the following behavior:
detox: {
behavior: {
cleanup: {
shutdownDevice: true,
},
init: {
exposeGlobals: false,
keepLockFile: false,
reinstallApp: true,
},
launchApp: 'auto',
},
},
and also call device.launchApp with the newInstance: true param set. I'm seeing that between test FILES, the app state completely resets, as I'd expect, but not between tests within the same suite. This is most noticeable via our auth state: the first test in a suite will log in to the app, and I'd expect the second to need to do the same, but the app is still logged in when the second starts running.
I've tried to set up a device.terminateApp in an afterEach, and that doesn't seem to do anything. I've also tried device.uninstallApp, but that results in a bunch of errors I haven't tried debugging yet.
From the docs (for Detox 20), it sounds like newInstance is supposed to be sufficient to reset state, but it looks like it doesn't wipe storage as part of that: how would I go about actually resetting state (including AsyncStorage) entirely?
Related
For some reasons when i try to run my cypress code it fails (during the first initialization) and it throws an error like the variables im setting out of the file doesn't exist. (when they actually are...)
After it fails i click on the re-run button and everything works perfectly, what im trying to avoid is the problem with the ghost variables at the beginning... I tried different approaches like setting the variable to an environment variable, and nothing seems to work.
I have this constants in an external file:
export const constants = {
access_token: "",
_id: "",
payment: {},
access_token_QR: "",
QRCode: "",
url: "https://google.com/"
}
And on each cypress test for example i have something like this:
it("login SSO", () => {
constants.access_token = "asfdaaFDSA"#$20ASDG0A"#$ASDJFAJM2"
}
Then after that it goes to the next test:
it("Another test", () => {
cy.log(constants.access_token) // it does print the code.
}
And when it reaches a test that does a cy.visit it doesn't detect the url constants.url but when i reload the cypress it works perfectly for some reason i can't explain.
Is there any setting im currently missing?
I tried setting the variable in the same file but is not passing until it reloads the website i believe is something related to cache that makes it works?
I found a jest mock for split.io for react-native. I am now trying to use this mock so that I do not receive network timeouts because split.io is trying to sync in the background. Here is the mock:
jest.mock('#splitsoftware/splitio-react-native', () => {
const splitio = jest.requireActual('#splitsoftware/splitio-react-native');
return {
...splitio,
SplitFactory: () => {
return splitio.SplitFactory({
core: {
authorizationKey: 'localhost',
},
// Mock your splits and treatments here
features: {},
sync: {
localhostMode: splitio.LocalhostFromObject(),
},
});
},
};
});
I currently put this in my detox init.js file, but it doesn't seem to be doing anything. The only way, so far, I have been able to get my tests to run is to just immediately destroy my SplitFactory as soon as I create it (not through the mock). Obviously, this isn't ideal since I'd have to change the code every time I wanted to run it. I tried creating a .mock.ts file, but that also didn't get read, and when I tried to adjust my metro.config.js, it just failed to run at all. Does anyone have any ideas of how I can get this to run properly in detox for iOS, or have experience with this?
I had the same issue with split.io and detox, when a particular split.io would block my tests indefinitely. The only work around i found was
await device.disableSynchronization();
found here
I want to close my browser instance whenever my test scenario fails,
The issue currently is my test execution proceeds to next scenario and because my last window is still looking for a locator or etc, even my next scenario fails.
Is there a way I can close my browser window if my test scenario fails in Nightwatch?
test_settings: {
default: {
launch_url: 'http://localhost',
page_objects_path: './e2e-nightwatch/ionic/objects',
selenium_host: '127.0.0.1',
selenium_port: 4444,
request_timeout_options: {
timeout: 7000,
retry_attempts: 5
},
end_session_on_fail:true,
skip_testcases_on_fail:true,
disable_colors: false,
screenshots: {
enabled: true,
on_failure: true,
on_error: true,
path: './e2e-nightwatch/ionic/screenshots'
},
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true,
"chromeOptions": {
"args": ["start-maximized"]
}
},
},
What you are probably observing, is not a failure but error (speaking Nightwatch language). This could be execution error, exception or something like that:
ERROR: Unable to locate element: "#someElement" using: css selector
This is not considered failure (and failure actually means failed assertion), thus skip_testcases_on_fail option won't have any effect (btw: this option is set to true by default).
There are 2 ways to solve this.
First (preferred):
Before performing any actions on elements, for instance doing .click('#someElement'), the good practice is to run assertion on the same selector:
// fails immediately if element is not present
browser.assert.elementPresent('#someElement')
// wait for element to be present for specified time in ms
browser.waitForElementPresent('#someElement', 2000)
Both methods will stop execution of your test run in case element is not present.
Second:
In case you don't want to use the first method for some reason or just curious, there is another way to stop execution of entire test run.
Within the test case you can define afterEach function which is fired after each test case completes. Inside this function you have access to the object containing stats of the current test run. What you can do is to simply check if error count is greater than 0 and pass error to the done() callback which will lead into interruption of entire test run:
module.exports = {
'Test case #1': function(browser) {},
afterEach: function(browser, done) {
done(browser.currentTest.results.errors ? new Error('Errors occured during the last test run') : null);
}
};
Let me know if it worked for you.
Yeah you can use skip_testcases_on_fail for this. In your config just add
skip_testcases_on_fail: true
This will finish out the current test step and then exit before executing any additional steps. You can see a full list of test settings here.
You might also be able to use end_session_on_fail. Depends on how you want it to work.
Driver.Dispose();
Closes the browser.
I am currently learning how to test Ember apps and I have an issue I cannot resolve for myself.
The problem is that when the test I wrote runs, it never ends. It just keeps running, like it has a promise that never resolves or something? This is the test:
test("User signs in and is redirected to his dashboard", function() {
visit('/');
fillIn('input#identification', 'test');
fillIn('input#password', 'test');
click('input#login');
andThen(function() {
ok(currentRouteName() === 'dashboard', 'redirected to dashboard');
});
});
The andThen function is never triggered, it seems like the promise of click never resolves. I made the routes and templates etc. so minimalistic as possible to avoid other interfering code.
Also I am using ember-simple-auth, maybe that this could explain any behaviour?
This is a screenshot of the problem:
I'm trying to connect to SoundCloud using CasperJS. What is interesting is once you signed in and rerun the login feature later, the previous login is still active. Before going any further, here is the code:
casper.thenOpen('https://soundcloud.com/', function() {
casper.click('.header__login');
popup = /soundcloud\.com\/connect/;
casper.waitForPopup(popup, function() {
casper.withPopup(popup, function() {
selectors = {
'#username': username,
'#password': password
};
casper.fillSelectors('form.log-in', selectors, false);
casper.click('#authorize');
});
});
});
If you run this code at least twice, you should see the following error appears:
CasperError: Cannot dispatch mousedown event on nonexistent selector: .header__login
If you analyse the logs you will see that the second time, you were redirected to https://soundcloud.com/stream meaning that you were already logged in.
I did some research to clear environments between each test but it seems that the following lines don't solve the problem.
phantom.clearCookies()
casper.clear()
localStorage.clear()
sessionStorage.clear()
Technically, I'm really interested about understanding what is happening here. Maybe SoundCloud built a system to also store some variables server-side. In this case, I would have to log out before login. But my question is how can I perfectly isolate and clear everything between each test? Does someone know how to make the environment unsigned between each test?
To clear server-side session cache, calling: phantom.clearCookies(); did the trick for me. This cleared my session between test files.
Example here:
casper.test.begin("Test", {
test: function(test) {
casper.start(
"http://example.com",
function() {
... //Some testing here
}
);
casper.run(function() {
test.done();
});
},
tearDown: function(test) {
phantom.clearCookies();
}
});
If you're still having issues, check the way you are executing your tests.
Where did you call casper.clear() ?
I think you have to call it immediately after you have opened a page like:
casper.start('http://www.google.fr/', function() {
this.clear(); // javascript execution in this page has been stopped
//rest of code
});
From the doc: Clears the current page execution environment context. Useful to avoid having previously loaded DOM contents being still active.