So I have recently stumbled across a "fun" thing for automation and test case runs in general - and that is that iOS is very persistent with the users cache and won't let you delete the apps cache.
The actual issue:
- first test case runs fine and logs in the user
- the second test case expects the user to be logged out | expects to run on a fresh app - without any left over cache from the previous user <- so because of that it FAILS
I have tried several solutions:
- adding capabilities like
noReset
or/andfullReset
- stopping the driver (deleting the app and reinstating it again)
- basically everything I could find - I tried
I have managed to fix the issue for SIMULATOR but not for the REAL DEVICE.
If you are doing any appium webdriver automation for your mobile applications - you should have encountered this issue and had to deal with it somehow - would really appreciate your opinion on this topic! (Also I am using SauceLabs for the real devices)
P.s. I don't want to make silly workarounds like loging out the user after each test case - so the next one could start from a fresh app and so on. IMHO this would be a really bad practise | shot-lived workaround.
Edit - code examples. Capabilities:
config.capabilities = [
{
platformName: 'iOS',
'appium:platformVersion': getRandomOsVersion(osVersions),
'appium:deviceName': 'iPhone .*',
'appium:automationName': 'XCUITest',
'appium:app': 'storage:filename=app.ipa',
'appium:autoAcceptAlerts': true,
'appium:connectHardwareKeyboard': true,
'appium:shouldTerminateApp': true,
'appium:newCommandTimeout': 240,
'sauce:options': {
build: buildName,
name: buildName,
allowTouchIdEnroll: false,
sauceLabsImageInjectionEnabled: false,
},
},
];
Test cases:
describe('Login functionality', () => {
beforeEach(async () => {
await driver.reset();
(await WelcomeScreen.getStartedButton).waitForDisplayed();
});
it('Login with user (finished profile)', async () => {
await WelcomeScreen.getStartedButton.click();
await LoginScreen.submitLogin(USER_CREDENTIALS.USER_WITH_FINISHED_PROFILE);
await expect(await FeaturesTourScreen.letsGetYouStarted).toBeDisplayed();
});
it('Login with user incorrect credentials', async () => {
await WelcomeScreen.getStartedButton.click();
await LoginScreen.submitLogin(USER_CREDENTIALS.INCORRECT_CREDENTIALS);
await expect(await LoginScreen.alertMesage).toBeDisplayed();
});
});
CodePudding user response:
Real Device background
Real devices behave differently in comparison to Simulators. When you install an iOS app on a real device it needs to be resigned so it is allowed to install the app. Removing an app "might" remove all data that has been stored on the device / keystore, but data could still be attached to your iCloud account. There are no Appium commands to remove the data stored in the keystore or in the app itself
WebdriverIO background
This is not even 100% specific for WebdriverIO, but when you run 2 tests (it
) from a single file the end state of the first test will be the starting state of the second test. You can control that with a beforeEach/afterEach
, but this will have no/less effect on real devices.
WebdriverIO spins up a single driver for every test file. In theory this should lead to a clean simulator / device when the second test-file is starting
Sauce Labs background
When you are using Sauce Labs you don't have the option to remove the app between the first and second it
, because when you remove the app it needs to be resigned and this is not supported. Options like noReset|fullReset
won't have an effect on iOS real devices.
If you need to have all data cleared then you need to:
- or have a backdoor in your app to do this through Appium
- run the second test case in a new spec file. WebdriverIO spins up a new instance for every test file and in between the app is removed and the device is cleaned
CodePudding user response:
I would suggest you ask the developers of the application to add data cleanup logic in the code itself that runs when a specific launch argument
is provided when starting the application. Then you can use the Appium capability processArguments
to provide that argument to the app when starting the test and the app itself will cleanup the data. Example for providing arguments from Appium issues, Appium XCUITest driver official docs describing the capability