Mock ImageCropPicker in React Native Detox - javascript

I'm trying to mock the react-native-image-crop-picker package (the openCamera function specifically) in Detox but I'm not managing to do it. Detox simply does not consider the mock.
.detoxrc.json:
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"uiHierarchy": "enabled",
"configurations": {
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "yarn detox:prepare",
"type": "android.emulator",
"device": {
"avdName": "Pixel_4_API_29"
}
}
}
}
.config.json:
{
"preset": "ts-jest",
"testEnvironment": "./environment",
"testRunner": "jest-circus/runner",
"testTimeout": 120000,
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true,
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)(e2e).js?(x)",
"**/__tests__/**/*.ts?(x)",
"**/?(*.)(e2e).ts?(x)"
]
}
config.js:
require('#babel/register')({
//cache: true,
presets: [require('metro-react-native-babel-preset')],
plugins: [require('#babel/plugin-transform-runtime').default],
only: ['./e2e', './ts', './js'],
ignore: ['node_modules'],
});
environment.js:
const {
DetoxCircusEnvironment,
SpecReporter,
WorkerAssignReporter,
} = require('detox/runners/jest-circus');
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config) {
super(config);
// Can be safely removed, if you are content with the default value (=300000ms)
this.initTimeout = 300000;
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
// This is strictly optional.
this.registerListeners({
SpecReporter,
WorkerAssignReporter,
});
}
}
module.exports = CustomDetoxEnvironment;
metro.config.js:
const blacklist = require('metro-config/src/defaults/blacklist');
const defaultSourceExts = require('metro-config/src/defaults/defaults')
.sourceExts;
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* #format
*/
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
/**
*
* Blacklist is a function that takes an array of regexes
* and combines them with the default blacklist to return a single regex.
*
*/
resolver: {
blacklistRE: blacklist([/.\/amplify\/.*/]),
sourceExts: process.env.RN_SRC_EXT
? process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts)
: defaultSourceExts,
},
};
E2E folder:
E2E Folder
ImageCropPicker.e2e.js:
import ImageCropPicker from 'react-native-image-crop-picker';
ImageCropPicker.openCamera = function openCamera() {
console.tron.log('mocked');
return {
mime: 'test',
data: 'test',
};
};
I also tried to put the ImageCropPicker.e2e.js file outside the mocks folder, but it did not work as well.
Detox, Node, Device and OS versions:
Detox: 17.6.0
Node: 10.23.0
Device: Pixel 4 API 29
OS: Linux Pop!_OS 20.10
React-Native: 0.62.0
Can you help me?
I appreciate your time!

Related

NestJS Application won't hot reload after using dotenv package

I try to configure hot reload on my Nestjs application using this article: https://docs.nestjs.com/recipes/hot-reload
I followed exactly the instructions in the first section ("With CLI") but it fails for me. But I do know the reason, just don't know how to resolve this issue. My hot reload script in package.json is exactly as the article says, except 1 change:
"start:dev": "dotenv -e ./envs/.env.development -e ../../prisma/.env.development nest build --watch",
This is my script. As you can see, I apply the process with some environment variables. When running in this way, application boots fine, but Hot Reload won't work. When booting only with "start:dev": "nest build --watch",
It runs with Hot Reload. (Note that I configure webpack in nest-cli.json file, this is why it missing in script statement).
Anyone could tell why applying my own envs makes this issue?
webpack.config.js file:
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');
const configuration = (options, webpack) => ({
...options,
entry: ['webpack/hot/poll?100', options.entry],
externals: [
nodeExternals({
allowlist: ['webpack/hot/poll?100'],
}),
],
plugins: [
...options.plugins,
new webpack.HotModuleReplacementPlugin(),
new webpack.WatchIgnorePlugin({
paths: [/\.js$/, /\.d\.ts$/],
}),
new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
],
});
module.exports = configuration;
nest-cli.json file:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"webpack": true,
"webpackConfigPath": "./webpack.config.js",
"deleteOutDir": true
}
}
main.ts file:
declare const module: any;
async function bootstrap() {
const prisma = new PrismaClient();
// * https://github.com/prisma/prisma/issues/5430#issuecomment-1098715558
await prisma.$runCommandRaw({
createIndexes: 'RefreshToken',
indexes: [
{
key: {
createdAt: 1,
},
name: 'Refresh Token Index',
expireAfterSeconds: JWT_REFRESH_TOKEN_DURATION_MINUTES * 60,
},
],
});
const app = await NestFactory.create(AppModule);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
const port = config.get('port', { infer: true });
await app.listen(port);
}
bootstrap();
Ny env file:
NODE_ENV="development"
PORT="3000"

Jest tests started failing with "Cannot use import statement outside a module" after using jail-monkey package in my React Native application

I have a React Native app in which I installed and used jail-monkey to check if the device is rooted. As soon as I added it, some of my Jest tests started failing with the following error:
SyntaxError: Cannot use import statement outside a module
> 3 | import JailMonkey from 'jail-monkey';
After googling I came upon this stack overflow thread which has many answers but neither of which helped me. That being said I imagine this problem has to do with the babel and jest configs - How to resolve "Cannot use import statement outside a module" in jest
My babel.config.js looks like this:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
require.resolve('babel-plugin-module-resolver'),
{
cwd: 'babelrc',
extensions: ['.ts', '.tsx', '.ios.tsx', '.android.tsx', '.js'],
alias: {
'#src': './src',
},
},
],
[
'module:react-native-dotenv',
{
moduleName: 'react-native-dotenv',
},
],
// Reanimated needs to be at the bottom of the list
'react-native-reanimated/plugin',
],
};
And my jest.config.js looks like this:
const { defaults: tsjPreset } = require('ts-jest/presets');
/** #type {import('#jest/types').Config.InitialOptions} */
module.exports = {
...tsjPreset,
preset: 'react-native',
transform: {
'^.+\\.jsx$': 'babel-jest',
},
// Lists all react-native dependencies
// that don't have compiled ES6 code
// and need to be ignored by the transformer
transformIgnorePatterns: [
'node_modules/(?!(react-native' +
'|react-navigation-tabs' +
'|react-native-splash-screen' +
'|react-native-screens' +
'|react-native-reanimated' +
'|#react-native' +
'|react-native-vector-icons' +
'|react-native-webview' +
')/)',
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
// Help Jest map the #src's added by babel transform
'^#src(.*)$': '<rootDir>/src$1',
// Allow Jest to mock static asset imports
'\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/assetMock.js',
// Mock SVG Component imports (from React Native SVG)
'\\.svg': '<rootDir>/__mocks__/svgMock.js',
},
setupFiles: ['./jest.setup.js'],
setupFilesAfterEnv: ['#testing-library/jest-native/extend-expect'],
};
I solved this issue by including jail-monkey in my transformIgnorePatterns on jest.config.js and them mocking the jailmonkey.js. In my case I have the file on __mocks__/jail-monkey/index.js with the following content:
export default {
jailBrokenMessage: () => '',
isJailBroken: () => false,
androidRootedDetectionMethods: {
rootBeer: {
detectRootManagementApps: false,
detectPotentiallyDangerousApps: false,
checkForSuBinary: false,
checkForDangerousProps: false,
checkForRWPaths: false,
detectTestKeys: false,
checkSuExists: false,
checkForRootNative: false,
checkForMagiskBinary: false,
},
jailMonkey: false,
},
hookDetected: () => false,
canMockLocation: () => false,
trustFall: () => false,
isOnExternalStorage: () => false,
isDebuggedMode: () => Promise.resolve(false),
isDevelopmentSettingsMode: () => Promise.resolve(false),
AdbEnabled: () => false,
};

Jest instantiating empty objects instead of class instances

I'm using ts-jest to test a JS/TS SDK/module. I'm running into a strange issue where a Jest test will run (no compile/import failures) but fail to correctly instantiate an object from the appropriate class.
test("Should build unit", () => {
const builder = new UnitBuilder("TEST_UNIT");
console.log(builder); // prints "{}"
const unit = builder
.addResource(...)
.build();
expect(unit.name).toBe("TEST_UNIT");
});
The test fails with: TypeError: builder.addResource is not a function since the instantiated object is empty. Here's the class in question:
export class UnitBuilder {
constructor(templateId: string) {
this.payload = {
templateId,
parameters: [],
};
}
public addResource = (resource: CreateResourcePayload) => {
// do stuff
};
public build = () => {
// do stuff
};
public payload: CreateUnitPayload;
}
I'm assuming this has something to do with the jest or ts-jest transpilation, e.g. babel, but perhaps it's something to do with the jest configuration as well?
jest.config.ts
import type { Config } from "#jest/types";
const config: Config.InitialOptions = {
preset: "ts-jest",
testEnvironment: "node",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
verbose: true,
automock: true,
testMatch: ["**/__tests/*.test.ts"],
roots: ["<rootDir>/src"],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
},
};
export default config;
Removing automock: true fixed the problem.

How do I add types to a Vite library build?

I followed the vite documentation for using library mode and I am able to produce a working component library.
I created the project with the vue-ts preset and in my component I have defined props with their types, and used some interfaces. But when I build the library, there are no types included.
How do I add types for the final build, either inferred from components automatically or manually with definition files?
More information
Here is some more information on my files:
tsconfig.json
{
"name": "#mneelansh/test-lib",
"private": false,
"version": "0.0.2",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"emitDeclarationOnly": true, // testing
"declaration": true, // testing
"main": "./dist/lib.umd.js",
"module": "./dist/lib.es.js",
"types": "./dist/main.d.ts",
"exports": {
".": {
"import": "./dist/lib.es.js",
"require": "./dist/lib.umd.js"
},
"./dist/style.css": "./dist/style.css"
},
"files": [
"dist"
],
"dependencies": {
"#types/node": "^17.0.25",
"vue": "^3.2.25"
},
"devDependencies": {
"#vitejs/plugin-vue": "^2.3.1",
"typescript": "^4.5.4",
"vite": "^2.9.5",
"vue-tsc": "^0.34.7"
}
}
I added the emitDeclarationOnly and declaration properties but that didn't help.
My vite.config.ts:
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
const path = require("path");
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, "src/index.ts"),
name: "Button",
fileName: (format) => `lib.${format}.js`,
},
rollupOptions: {
external: ["vue"],
output: {
globals: {
vue: "Vue",
},
},
},
},
plugins: [vue()],
});
You can use vite-plugin-dts
import dts from "vite-plugin-dts";
export default defineConfig({
plugins: [
dts({
insertTypesEntry: true,
}),
],
Usually with vite and typescript project you need add type checking before build, because vite doesn't do it by himself. Here I'm also using vite-plugin-dts as in post from Julien Kode, and for type checking rollup-plugin-typescript2.
Finally my vite.config.js:
import { defineConfig } from 'vite';
import Vue from '#vitejs/plugin-vue2';
import dts from 'vite-plugin-dts';
import rollupTs from 'rollup-plugin-typescript2';
export default defineConfig({
plugins: [
Vue(),
dts({ insertTypesEntry: true }),
// only for type checking
{
...rollupTs({
check: true,
tsconfig: './tsconfig.json',
tsconfigOverride: {
noEmits: true,
},
}),
// run before build
enforce: 'pre',
},
],
build: {
sourcemap: true,
lib: {
entry: './src/index.ts',
fileName: 'index',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: [
'vue',
'vue-class-component',
'vue-property-decorator',
'vuex',
'vuex-class',
],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
},
},
},
},
});
You could write your own Vite plugin to leverage tsc at the buildEnd step to accomplish this. As other answers have suggested, you can use the flag emitDeclarationOnly.
See this simple example:
import { type Plugin } from 'vite';
import { exec } from 'child_process';
const dts: Plugin = {
name: 'dts-generator',
buildEnd: (error?: Error) => {
if (!error) {
return new Promise((res, rej) => {
exec('tsc --emitDeclarationOnly', (err) => (err ? rej(err) : res()));
});
}
},
};
Then add to your plugins field of your vite config
Personally I think a nicer way to do it is with vue-tsc:
vue-tsc --declaration --emitDeclarationOnly
See https://stackoverflow.com/a/70343443/398287

Automated Webpack Project Setup through node

My goal is to let a webpack project be setup through node command crateEntireWepbackProject.js file.
I want to execute commands on the shell from a js file, so I can let them run automatically and later on also include custom specifications for a project.
The js file is not from within webpack, but has the commands to create a wepback project from scratch and makes the installs etc. just by me typing node createEntireWebpackProject.js
You do not need to write it from scratch. The best practice is using yeoman. There are a lot of generators with webpack. For example:
const Generator = require('yeoman-generator');
const mkdirp = require('mkdirp');
const path = require('path');
module.exports = class extends Generator {
prompting() {
this.log('Welcome to the classy example generator!');
const prompts = [
{
type: 'input',
name: 'name',
message: 'Name?',
default: this.appname,
}];
return this.prompt(prompts).then((props) => {
this.props = props;
});
}
default() {
if (path.basename(this.destinationPath()) !== this.props.name) {
this.log(
`Your application must be inside a folder named ${this.props.name}`);
this.log('I\'ll automatically create this folder.');
mkdirp(this.props.name);
this.destinationRoot(this.destinationPath(this.props.name));
}
}
writing() {
this.createPackageJson();
this.copyFiles();
this.fillTemplates();
this.makeCommands();
}
install() {
this.npmInstall(['bunyan', 'dotenv-safe'], { save: true });
this.npmInstall(['eslint', 'eslint-config-airbnb-base', 'eslint-plugin-import', 'jest'], { 'save-dev': true });
}
createPackageJson() {
this.fs.extendJSON('package.json', {
name: this.props.name,
version: '0.1.0',
main: 'src/app.js',
scripts: {
cs: 'eslint src/* __tests__/*',
'cs:fix': 'eslint src/* __tests__/* --fix',
start: 'node src/app.js',
test: 'npm run cs && jest',
},
dependencies: {},
devDependencies: {},
engines: {
node: '^8.1.0',
},
private: true,
jest: {
testEnvironment: 'node',
transform: {},
collectCoverage: true,
},
});
}
copyFiles() {
[
'.dockerignore',
'.eslintrc.json',
'src/app.js',
].forEach(name => this.fs.copy(this.templatePath(name), this.destinationPath(name)));
}
fillTemplates() {
this.fs.copyTpl(
this.templatePath('README.md'),
this.destinationPath('README.md'),
{
name: this.props.name,
});
}
makeCommands() {
this.spawnCommandSync('git' ['init']);
this.spawnCommandSync('git', ['add', '.']);
this.spawnCommandSync('git', ['commit', '-am', '"yo scaffolded app"']);
}
};

Categories

Resources