DetoxRuntimeError: Detox instance has not been initialized - ios

After updating to react-native 0.63.3 and xcode 12.0.1 the tests are not working anymore. First had some issues building detox but that was solved. Now this error is there and I cannot go further:
DetoxRuntimeError: Detox instance has not been initialized
HINT: Make sure to call detox.init() before your test begins
detox.init() is being called and I can see it in the logs.
This is my init.js
import { device } from 'detox';
const detox = require('detox');
const config = require('../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');
const assignReporter = require('detox/runners/jest/assignReporter');
jest.setTimeout(180000);
jasmine.getEnv().addReporter(adapter);
jasmine.getEnv().addReporter(specReporter);
jasmine.getEnv().addReporter(assignReporter);
beforeAll(async () => {
await detox.init(config, { launchApp: false });
const permissions = {
notifications: 'NO',
camera: 'NO',
};
await device.launchApp({ permissions });
});
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});
My environment:
React-Native: 0.63.3 Detox: 17.10.3 xcode: 12.0.1 iOS: 14.0
Running on ios.sim.debug

After long search I have found out that the actual tests are in a submodule/subrepo of the project. The tests are triggered from the app root level. Before the update even those tests were triggered correctly. Now, they only work if I move them to from the submodule level to the app root level

Related

iOS in app purchases through cordova-plugin-purchase?

I'm using Capacitor (but not Ionic) to package a SvelteKit application for iOS and am trying to get an in-app-purchase working.
Capacitor's page on in-app-purchases is surprisingly unhelpful. I've done my best and:
I have the products set up in appstoreconnect and they're status is "ready to submit"
I've installed cordova-plugin-purchase and run npx cap update and npx cap sync and it's installing
[info] Found 1 Cordova plugin for ios:
cordova-plugin-purchase#13.0.3
I've tried to make the simplest test I could just to see what's going on:
import 'cordova-plugin-purchase'; // This seems to add `CdvPurchase` to the global scope.
function buy() {
const {store, ProductType, Platform} = CdvPurchase;
store.verbosity = store.DEBUG;
store.register([{
type: ProductType.CONSUMABLE,
id: "my-product-id",
platform: Platform.APPLE_APPSTORE,
}]);
store.error(e => {
console.log('error', e);
});
store.when()
.productUpdated(() => {
console.log('product updated', product);
})
.approved(value => {
console.log('approved', value);
})
.verified(value => {
console.log('verified', value);
})
.finished(value => {
console.log('finished', value);
});
store.ready(() => {
console.log('ready', store.products);
store.order('my-product-id');
});
store.initialize(Platform.APPLE_APPSTORE)
.then(() => {
console.log('initialize resolved', store.products);
store.order('my-product-id');
});
}
But I run the buy function, all I get is:
[log] - [CordovaPurchase] INFO: initialize()
The store never reports as ready. None of the listeners are triggered, not even .error().
Have I missed something? How do I debug this?

Electron Deeplink is not working, it does not respond at all with "gotTheLock", unless I run it directly via CMD line calling electron.exe

I've been trying to get deeplinks to work to do oauth for like 4 weeks:
on different boilerplates
on raw quick start of electron
on electron-forge with webpack.
None of them work while in dev mode, and only does while packaged.
I do not understand why it only works if I target command line the electron.exe and pass my app. OR when the app is packaged. If it's in development mode, it simply does not work.
I think? that the gotTheLock runs app.quit(), because in instances where I put the createWindow() outside of the lock if/else function, a window briefly opens and then closes immediately. For some reason it's opening a new instance completely? When createWindow() is inside, I basically see nothing happen.
I'm on Windows, I see nothing about forge that would cause issues or need extra setup in the forge config/package.json since I am on Windows
There's something fundamental flying over my head. Currently, my latest attempt is with the new 6.0 electron-forge from here with the following npm command to generate:
npm init electron-app#latest my-app --template=webpack cd my-app npm start
Here is my "main" which is called index.js here.
index.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
app.quit();
}
let mainWindow;
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}
const createWindow = () => {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'index.html'));
// Open the DevTools.
mainWindow.webContents.openDevTools();
};
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
})
app.on('ready', createWindow);
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
ipcMain.on('shell:open', () => {
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, 'index.html')
shell.openExternal(pagePath)
})
I've tried so many iterations i'm honestly just lost. What's wrong with this that the electron-forge dev mode doesn't like?
As far as any other code is concerned, it's "as-is" from that npm command with the latest 6.0 electron-forge with webpack template. Only the index.js was modified

launching Theia based electron app (artifact/package) isn't working

Almost new in using playwright. Exploring the things and checking what we can do with this tool.
I am trying to launch our Theia based electon app in Ubuntu 18.04 with below source.
const { _electron: electron } = require('playwright');
//const { _electron } = require('playwright');
//import { test, expect, Page } from '#playwright/test';
(async () => {
// Launch Electron app.
const electronApp = await electron.launch('./my_executable_file_path');
//this executable is an artifact/packgae
})();
test.describe('New Todo', () => {
test('should allow me to add todo items', async ({ page }) => {
//let's not do anything before the app launch.
});
});
In my package.json file, i have this already
"devDependencies": {
"#playwright/test": "^1.20.2",
I can successfully run test cases based on the browser but not able to launch the electron app.
electron.launch: Cannot find module 'electron/index.js'
We don't have this index.js in our jenkins generated artifact.
This is how I launched electron successfully
const electronApp = await _electron.launch({
args: ['theia-electron-main.js'],
cwd: 'cube-electron/apps/studio/electron/scripts'
});

My spectron app.client doesn't contains all the methods

I'm trying to test my electron app using spectron and mocha, here is my file 'first.js' containing my tests:
const assert = require('assert');
const path = require('path');
const {Application} = require('spectron');
const electronPath = require('electron');
describe('GULP Tests', function () {
this.timeout(30000)
const app = new Application({
path: electronPath,
args: [path.join(__dirname, '..', 'main.js')]
});
//Start the electron app before each test
before(() => {
return app.start();
});
//Stop the electron app after completion of each test
after(() => {
if (app && app.isRunning()) {
return app.stop();
}
});
it('Is window opened', async () => {
const count = await app.client.getWindowCount();
return assert.equal(count, 1);
});
it('Clicks on the project creation button', async () => {
await app.client.waitUntilWindowLoaded();
const title = await app.client.
console.log(title);
return assert.equal(title, 'Welcome to GULP, !');
});
});
My first test is passing, but for the second one i'd like to do a click on an element, but my app.client does not contain a .click methods, and also no getText or getHTML. I've tried to import browser from webdriverio but it was the same problem, I get an error when testing saying me that those methods doesn't exists. I've red the spectron documentation and they're using .click and .getText methods regularly, why I don't get them ? I've imported spectron as it's said in the documentation to.
Thanks.
I have struggled with the same issue for a while. After much trial and error i changed my async methods to normal functions.
it('Clicks on the project creation button', function() {
app.client.waitUntilWindowLoaded();
const title = await app.client.
console.log(title);
return assert.equal(title, 'Welcome to GULP, !');
});
Strange but it worked for me. hopefully it helps.

React native: TypeError: null is not an object (evaluating 'SplashScreen.preventAutoHide')

My react native app was working just fine before I used expo eject. I ejected it because I now intend to build and release the app to the ios app store. As soon as I attempt to start the ejected app using react-native run-ios after it's been ejected I get the exception below.
Please could someone help to understand what's causing this issue and how to tackle it?
react Native versions as follows:
react-native-cli: 2.0.1
react-native: 0.61.5
TypeError: null is not an object (evaluating 'SplashScreen.preventAutoHide')
This error is located at:
in AppLoading (at AppLoading.js:52)
in AppLoading (at App.js:464)
in App (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in RCTView (at AppContainer.js:119)
in AppContainer (at renderApplication.js:39)
preventAutoHide
SplashScreen.js:4:21
AppLoading#constructor
AppLoadingNativeWrapper.js:6:8
renderRoot
[native code]:0
runRootCallback
[native code]:0
renderApplication
renderApplication.js:52:52
runnables.appKey.run
AppRegistry.js:116:10
runApplication
AppRegistry.js:197:26
callFunctionReturnFlushedQueue
[native code]:0
The AppLoading component is not available in the bare workflow. As #gaurav-roy said you have to refactor your code.
Install the expo-splash-screen package with npm install expo-splash-screen
Add a splash-screen to your Android and iOS projects. Run npm run expo-splash-screen --help and follow the instructions of this CLI tool. (Because of a bug you might have to run the command again with the -p "ios" flag if it only adds the SplashScreen for Android after running it.
Change your code inside App.tsx in a similar way as in this example.
If you're working with hooks you probably want to add an useEffect
hook with an empty dependency list which runs an async function. Here an example of how it could be done:
const App = (props: Props) => {
const [isLoadingComplete, setLoadingComplete] = useState(false);
const init = async () => {
try {
// Keep on showing the SlashScreen
await SplashScreen.preventAutoHideAsync();
await loadResourcesAsync();
} catch (e) {
console.warn(e);
} finally {
setLoadingComplete(true);
// Hiding the SplashScreen
await SplashScreen.hideAsync();
}
useEffect(() => {
init();
}, []);
const renderApp = () => {
if (!isLoadingComplete && !props.skipLoadingScreen) {
return null;
}
return (
<Main />
);
};
return <StoreProvider>{renderApp()}</StoreProvider>;
}
As its evident from docs , SplashScreen is an inbuilt api for expo apps, and since you ejected it , it throws an error since it cant be used.
You can see this in the docs expo splashscreen .
First you should download npm i expo-splash-screen
And then change your import statement to :
import * as SplashScreen from 'expo-splash-screen';
Hope it helps. feel free for doubts
After looking through this SO page and then digging into some links, especially this expo page where they kind of provide a solution for this, I was able to get my app running after about 3 hours of struggle. They haven't added any functional component example, so I am sharing my code below in case someone came here looking for the solution.
import { Asset } from "expo-asset";
import * as Font from "expo-font";
import React, { useState, useEffect } from "react";
import { Platform, StatusBar, StyleSheet, View } from "react-native";
import { Ionicons } from "#expo/vector-icons";
import * as SplashScreen from 'expo-splash-screen';
import AppNavigator from "./navigation/AppNavigator";
export default props => {
const [isLoadingComplete, setLoadingComplete] = useState(false);
const theme = {
...DefaultTheme,
roundness: 2,
colors: {
...DefaultTheme.colors,
primary: "#E4002B",
accent: "#E4002B",
},
};
useEffect(() => {
async function asyncTasks() {
try {
await SplashScreen.preventAutoHideAsync();
} catch (e) {
console.warn(e);
}
await loadResourcesAsync()
setLoadingComplete(true);
}
asyncTasks()
}, []);
return (
!isLoadingComplete && !props.skipLoadingScreen ? null :
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
async function loadResourcesAsync() {
await Promise.all([
Asset.loadAsync([
require("./assets/images/logo.png") // Load your resources here (if any)
]),
Font.loadAsync({
// You can remove this if you are not loading any fonts
"space-mono": require("./assets/fonts/SpaceMono-Regular.ttf"),
}),
]);
await SplashScreen.hideAsync();
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
});
This solved it for me for an ejected expo app. Looks like expo was referencing it wrongly.
https://github.com/expo/expo/issues/7718#issuecomment-610508510
What worked for me was updating node_modules/expo/build/launch/splashScreen.js to the following as suggested by adamsolomon1986 in the repo (issue #7718):
import { NativeModules } from 'react-native';
import* as SplashScreen from 'expo-splash-screen'
export function preventAutoHide() {
if (SplashScreen.preventAutoHide) {
SplashScreen.preventAutoHide();
}
}
export function hide() {
if (SplashScreen.hide) {
SplashScreen.hide();
}
}
//# sourceMappingURL=SplashScreen.js.map

Resources