-
Notifications
You must be signed in to change notification settings - Fork 253
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(react-native): move react navigation scenarios to dynamic test f…
…ixture
- Loading branch information
1 parent
c67b83b
commit 6cbe7c9
Showing
6 changed files
with
294 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ if (!process.env.REGISTRY_URL) { | |
|
||
const notifierVersion = process.env.NOTIFIER_VERSION || common.determineVersion() | ||
|
||
const rnVersion = process.env.RN_VERSION | ||
const reactNativeVersion = process.env.RN_VERSION | ||
const ROOT_DIR = resolve(__dirname, '../') | ||
|
||
let fixturePath = 'test/react-native/features/fixtures/generated/' | ||
|
@@ -25,12 +25,21 @@ if (process.env.RCT_NEW_ARCH_ENABLED === '1') { | |
fixturePath += 'old-arch/' | ||
} | ||
|
||
const fixtureDir = resolve(ROOT_DIR, fixturePath, rnVersion) | ||
const fixtureDir = resolve(ROOT_DIR, fixturePath, reactNativeVersion) | ||
|
||
const replacementFilesDir = resolve(ROOT_DIR, 'test/react-native/features/fixtures/app/dynamic/') | ||
|
||
const DEPENDENCIES = [ | ||
'[email protected]' | ||
'[email protected]', | ||
`@bugsnag/react-native@${notifierVersion}` | ||
] | ||
|
||
const REACT_NAVIGATION_DEPENDENCIES = [ | ||
`@bugsnag/plugin-react-navigation@${notifierVersion}`, | ||
'@react-navigation/native', | ||
'@react-navigation/native-stack', | ||
'react-native-screens', | ||
'react-native-safe-area-context' | ||
] | ||
|
||
if (!process.env.SKIP_GENERATE_FIXTURE) { | ||
|
@@ -40,72 +49,12 @@ if (!process.env.SKIP_GENERATE_FIXTURE) { | |
} | ||
|
||
// create the test fixture | ||
const RNInitArgs = [`react-native@${process.env.RN_VERSION}`, 'init', 'reactnative', '--directory', fixtureDir, '--version', rnVersion, '--npm', '--skip-install'] | ||
const RNInitArgs = [`react-native@${process.env.RN_VERSION}`, 'init', 'reactnative', '--directory', fixtureDir, '--version', reactNativeVersion, '--npm', '--skip-install'] | ||
execFileSync('npx', RNInitArgs, { stdio: 'inherit' }) | ||
|
||
// replace the App.js/App.tsx file with our own App.js file | ||
fs.readdirSync(resolve(fixtureDir)) | ||
.filter((file) => /App\.[tj]sx?$/.test(file)) | ||
.map((file) => fs.unlinkSync(resolve(fixtureDir, file))) | ||
|
||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'App.js'), | ||
resolve(fixtureDir, 'App.js') | ||
) | ||
|
||
// replace the AndroidManifest.xml file with our own | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'android/AndroidManifest.xml'), | ||
resolve(fixtureDir, 'android/app/src/main/AndroidManifest.xml') | ||
) | ||
|
||
// replace the Info.plist file with our own | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'ios/Info.plist'), | ||
resolve(fixtureDir, 'ios/reactnative/Info.plist') | ||
) | ||
|
||
// copy the exportOptions.plist file | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'ios/exportOptions.plist'), | ||
resolve(fixtureDir, 'exportOptions.plist') | ||
) | ||
|
||
// update pbxproj | ||
let pbxProjContents = fs.readFileSync(`${fixtureDir}/ios/reactnative.xcodeproj/project.pbxproj`, 'utf8') | ||
pbxProjContents = pbxProjContents.replaceAll('org.reactjs.native.example', 'com.bugsnag.fixtures') | ||
replaceGeneratedFixtureFiles() | ||
|
||
fs.writeFileSync(`${fixtureDir}/ios/reactnative.xcodeproj/project.pbxproj`, pbxProjContents) | ||
|
||
// update Podfile | ||
let podfileContents = fs.readFileSync(`${fixtureDir}/ios/Podfile`, 'utf8') | ||
|
||
// use static frameworks (this fixes an issue with react-native-file-access on 0.75) | ||
if (parseFloat(rnVersion) >= 0.75) { | ||
podfileContents = podfileContents.replace(/target 'reactnative' do/, 'use_frameworks! :linkage => :static\ntarget \'reactnative\' do') | ||
} | ||
|
||
// disable Flipper | ||
if (podfileContents.includes('use_flipper!')) { | ||
podfileContents = podfileContents.replace(/use_flipper!/, '# use_flipper!') | ||
} else if (podfileContents.includes(':flipper_configuration')) { | ||
podfileContents = podfileContents.replace(/:flipper_configuration/, '# :flipper_configuration') | ||
} | ||
|
||
fs.writeFileSync(`${fixtureDir}/ios/Podfile`, podfileContents) | ||
|
||
const fixtureDependencyArgs = DEPENDENCIES.join(' ') | ||
|
||
// install test fixture dependencies and local packages | ||
execSync(`npm install --save ${fixtureDependencyArgs}`, { cwd: fixtureDir, stdio: 'inherit' }) | ||
|
||
// install @bugsnag/react-native from the registry | ||
execSync(`npm install --save @bugsnag/react-native@${notifierVersion} --registry ${process.env.REGISTRY_URL}`, { cwd: fixtureDir, stdio: 'inherit' }) | ||
|
||
// install the scenario launcher package | ||
const scenarioLauncherPackage = `${ROOT_DIR}/test/react-native/features/fixtures/scenario-launcher` | ||
execSync(`npm pack ${scenarioLauncherPackage} --pack-destination ${fixtureDir}`, { cwd: ROOT_DIR, stdio: 'inherit' }) | ||
execSync('npm install --save bugsnag-react-native-scenarios-1.0.0.tgz', { cwd: fixtureDir, stdio: 'inherit' }) | ||
installFixtureDependencies() | ||
} | ||
|
||
if (process.env.BUILD_ANDROID === 'true' || process.env.BUILD_ANDROID === '1') { | ||
|
@@ -163,3 +112,114 @@ if (process.env.BUILD_IOS === 'true' || process.env.BUILD_IOS === '1') { | |
|
||
execFileSync('xcrun', exportArgs, { cwd: fixtureDir, stdio: 'inherit' }) | ||
} | ||
|
||
function installFixtureDependencies() { | ||
if (!process.env.RCT_NEW_ARCH_ENABLED) { | ||
DEPENDENCIES.push(...REACT_NAVIGATION_DEPENDENCIES) | ||
} | ||
|
||
const fixtureDependencyArgs = DEPENDENCIES.join(' ') | ||
|
||
// install test fixture dependencies | ||
execSync(`npm install --save ${fixtureDependencyArgs} --registry ${process.env.REGISTRY_URL}`, { cwd: fixtureDir, stdio: 'inherit' }) | ||
|
||
// install the scenario launcher package | ||
const scenarioLauncherPackage = `${ROOT_DIR}/test/react-native/features/fixtures/scenario-launcher` | ||
execSync(`npm pack ${scenarioLauncherPackage} --pack-destination ${fixtureDir}`, { cwd: ROOT_DIR, stdio: 'inherit' }) | ||
execSync('npm install --save bugsnag-react-native-scenarios-1.0.0.tgz', { cwd: fixtureDir, stdio: 'inherit' }) | ||
} | ||
|
||
/** Replace native files generated by react-native cli with pre-configured files */ | ||
function replaceGeneratedFixtureFiles() { | ||
// replace the App.js/App.tsx file with our own App.js file | ||
fs.readdirSync(resolve(fixtureDir)) | ||
.filter((file) => /App\.[tj]sx?$/.test(file)) | ||
.map((file) => fs.unlinkSync(resolve(fixtureDir, file))) | ||
|
||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'App.js'), | ||
resolve(fixtureDir, 'App.js') | ||
) | ||
|
||
// replace the AndroidManifest.xml file with our own | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'android/AndroidManifest.xml'), | ||
resolve(fixtureDir, 'android/app/src/main/AndroidManifest.xml') | ||
) | ||
|
||
// replace the Info.plist file with our own | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'ios/Info.plist'), | ||
resolve(fixtureDir, 'ios/reactnative/Info.plist') | ||
) | ||
|
||
// copy the exportOptions.plist file | ||
fs.copyFileSync( | ||
resolve(replacementFilesDir, 'ios/exportOptions.plist'), | ||
resolve(fixtureDir, 'exportOptions.plist') | ||
) | ||
|
||
// update pbxproj | ||
let pbxProjContents = fs.readFileSync(`${fixtureDir}/ios/reactnative.xcodeproj/project.pbxproj`, 'utf8') | ||
pbxProjContents = pbxProjContents.replaceAll('org.reactjs.native.example', 'com.bugsnag.fixtures') | ||
|
||
fs.writeFileSync(`${fixtureDir}/ios/reactnative.xcodeproj/project.pbxproj`, pbxProjContents) | ||
|
||
// update Podfile | ||
let podfileContents = fs.readFileSync(`${fixtureDir}/ios/Podfile`, 'utf8') | ||
|
||
// use static frameworks (this fixes an issue with react-native-file-access on 0.75) | ||
if (parseFloat(reactNativeVersion) >= 0.75) { | ||
podfileContents = podfileContents.replace(/target 'reactnative' do/, 'use_frameworks! :linkage => :static\ntarget \'reactnative\' do') | ||
} | ||
|
||
// disable Flipper | ||
if (podfileContents.includes('use_flipper!')) { | ||
podfileContents = podfileContents.replace(/use_flipper!/, '# use_flipper!') | ||
} else if (podfileContents.includes(':flipper_configuration')) { | ||
podfileContents = podfileContents.replace(/:flipper_configuration/, '# :flipper_configuration') | ||
} | ||
|
||
fs.writeFileSync(`${fixtureDir}/ios/Podfile`, podfileContents) | ||
|
||
// react navigation setup | ||
const fileExtension = parseFloat(reactNativeVersion) < 0.73 ? 'java' : 'kt' | ||
let mainActivityPattern, mainActivityReplacement | ||
if (fileExtension === 'java') { | ||
mainActivityPattern = 'public class MainActivity extends ReactActivity {' | ||
mainActivityReplacement = ` | ||
import android.os.Bundle; | ||
public class MainActivity extends ReactActivity { | ||
/** | ||
* Required for react-navigation/native implementation | ||
* https://reactnavigation.org/docs/getting-started/#installing-dependencies-into-a-bare-react-native-project | ||
*/ | ||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(null); | ||
} | ||
` | ||
} else if (fileExtension === 'kt') { | ||
mainActivityPattern = 'class MainActivity : ReactActivity() {' | ||
mainActivityReplacement = ` | ||
import android.os.Bundle | ||
class MainActivity : ReactActivity() { | ||
/** | ||
* Required for react-navigation/native implementation | ||
* https://reactnavigation.org/docs/getting-started/#installing-dependencies-into-a-bare-react-native-project | ||
*/ | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(null) | ||
} | ||
` | ||
} | ||
|
||
const mainActivityPath = `${fixtureDir}/android/app/src/main/java/com/reactnative/MainActivity.${fileExtension}` | ||
let mainActivityContents = fs.readFileSync(mainActivityPath, 'utf8') | ||
mainActivityContents = mainActivityContents.replace(mainActivityPattern, mainActivityReplacement) | ||
fs.writeFileSync(mainActivityPath, mainActivityContents) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
...es/fixtures/scenario-launcher/src/scenarios/ReactNavigationBreadcrumbsDisabledScenario.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import Scenario from './Scenario' | ||
import Bugsnag from '@bugsnag/react-native' | ||
import BugsnagPluginReactNavigation from '@bugsnag/plugin-react-navigation' | ||
import * as React from 'react' | ||
import { View, Text } from 'react-native' | ||
import { NavigationContainer } from '@react-navigation/native' | ||
import { createNativeStackNavigator } from '@react-navigation/native-stack' | ||
|
||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) | ||
|
||
export class ReactNavigationBreadcrumbsDisabledScenario extends Scenario { | ||
constructor (configuration, jsConfig) { | ||
super() | ||
configuration.enabledBreadcrumbTypes = ['process', 'request', 'log'] | ||
jsConfig.plugins = [new BugsnagPluginReactNavigation()] | ||
} | ||
|
||
view () { | ||
const BugsnagNavigationContainer = Bugsnag.getPlugin('reactNavigation').createNavigationContainer(NavigationContainer) | ||
const Stack = createNativeStackNavigator() | ||
return ( | ||
<BugsnagNavigationContainer> | ||
<Stack.Navigator> | ||
<Stack.Screen | ||
name="Home" | ||
component={ HomeScreen } | ||
/> | ||
<Stack.Screen | ||
name="Details" | ||
component={ DetailsScreen } | ||
/> | ||
</Stack.Navigator> | ||
</BugsnagNavigationContainer> | ||
) | ||
} | ||
|
||
run () { | ||
} | ||
} | ||
|
||
function HomeScreen ({ navigation }) { | ||
React.useEffect(() => { | ||
(async () => { | ||
await delay(100) | ||
Bugsnag.notify(new Error('HomeNavigationError')) | ||
await delay(250) | ||
navigation.navigate('Details') | ||
})() | ||
}, []) | ||
|
||
return ( | ||
<View style={ { flex: 1, alignItems: 'center', justifyContent: 'center' } }> | ||
<Text>Home Screen</Text> | ||
</View> | ||
) | ||
} | ||
|
||
function DetailsScreen ({ navigation }) { | ||
React.useEffect(() => { | ||
(async () => { | ||
await delay(100) | ||
Bugsnag.notify(new Error('DetailsNavigationError')) | ||
await delay(250) | ||
throw new Error('DetailsNavigationUnhandledError') | ||
})() | ||
}, []) | ||
|
||
return ( | ||
<View style={ { flex: 1, alignItems: 'center', justifyContent: 'center' } }> | ||
<Text>Details Screen</Text> | ||
</View> | ||
) | ||
} |
Oops, something went wrong.