├── .npmignore
├── ios
├── e2eTests.app
│ ├── PkgInfo
│ ├── e2eTests
│ ├── Info.plist
│ ├── Base.lproj
│ │ └── LaunchScreen.nib
│ ├── Frameworks
│ │ ├── XCTest.framework
│ │ │ ├── XCTest
│ │ │ ├── Info.plist
│ │ │ ├── Modules
│ │ │ │ └── module.modulemap
│ │ │ ├── en.lproj
│ │ │ │ └── InfoPlist.strings
│ │ │ ├── XPCServices
│ │ │ │ ├── xctestSymbolicator.xpc
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ ├── xctestSymbolicator
│ │ │ │ │ ├── version.plist
│ │ │ │ │ └── _CodeSignature
│ │ │ │ │ │ └── CodeResources
│ │ │ │ └── XCUIRecorderService.xpc
│ │ │ │ │ ├── Info.plist
│ │ │ │ │ ├── XCUIRecorderService
│ │ │ │ │ ├── version.plist
│ │ │ │ │ └── _CodeSignature
│ │ │ │ │ └── CodeResources
│ │ │ ├── version.plist
│ │ │ └── Headers
│ │ │ │ ├── XCTestErrors.h
│ │ │ │ ├── XCUISiriService.h
│ │ │ │ ├── XCTNSPredicateExpectation.h
│ │ │ │ ├── XCUIRemote.h
│ │ │ │ ├── XCUIDevice.h
│ │ │ │ ├── XCTestCaseRun.h
│ │ │ │ ├── XCTestSuiteRun.h
│ │ │ │ ├── XCTDarwinNotificationExpectation.h
│ │ │ │ ├── XCTestObservationCenter.h
│ │ │ │ ├── XCTestLog.h
│ │ │ │ ├── XCUIApplication.h
│ │ │ │ ├── XCTestProbe.h
│ │ │ │ ├── XCTNSNotificationExpectation.h
│ │ │ │ ├── XCTestObserver.h
│ │ │ │ ├── XCTestDefines.h
│ │ │ │ ├── XCUIElementAttributes.h
│ │ │ │ ├── XCTestExpectation.h
│ │ │ │ ├── XCUIKeyboardKeys.h
│ │ │ │ ├── XCUICoordinate.h
│ │ │ │ ├── XCTest.h
│ │ │ │ ├── XCUIElementTypes.h
│ │ │ │ ├── XCTestSuite.h
│ │ │ │ ├── XCAbstractTest.h
│ │ │ │ ├── XCTKVOExpectation.h
│ │ │ │ ├── XCUIElementQuery.h
│ │ │ │ ├── XCTestObservation.h
│ │ │ │ └── XCUIElementTypeQueryProvider.h
│ │ └── IDEBundleInjection.framework
│ │ │ ├── Info.plist
│ │ │ ├── IDEBundleInjection
│ │ │ ├── version.plist
│ │ │ └── _CodeSignature
│ │ │ └── CodeResources
│ └── PlugIns
│ │ ├── e2eTestsTests.xctest
│ │ ├── Info.plist
│ │ ├── e2eTestsTests
│ │ └── _CodeSignature
│ │ │ └── CodeResources
│ │ └── e2eTestsTests.xctest.dSYM
│ │ └── Contents
│ │ ├── Resources
│ │ └── DWARF
│ │ │ └── e2eTestsTests
│ │ └── Info.plist
├── e2eTests
│ ├── AppDelegate.h
│ ├── main.m
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.m
│ ├── Info.plist
│ └── Base.lproj
│ │ └── LaunchScreen.xib
├── e2eTestsTests
│ ├── Info.plist
│ └── e2eTestsTests.m
└── e2eTests.xcodeproj
│ └── xcshareddata
│ └── xcschemes
│ └── e2eTests.xcscheme
├── .gitattributes
├── _config.yml
├── index.ios.js
├── index.web.js
├── .babelrc
├── index.android.js
├── packages
├── server
│ ├── index.html
│ ├── start.js
│ ├── index.test.js
│ └── index.js
├── app
│ └── src
│ │ ├── __mocks__
│ │ └── componentLoader.js
│ │ ├── components
│ │ ├── __mocks__
│ │ │ └── fructoseComponent.js
│ │ ├── navigation
│ │ │ ├── back-icon.png
│ │ │ ├── forward-icon.png
│ │ │ ├── parentNavigationItem.test.js
│ │ │ ├── __snapshots__
│ │ │ │ ├── navigation.test.js.snap
│ │ │ │ ├── parentNavigationItem.test.js.snap
│ │ │ │ └── navigationHeader.test.js.snap
│ │ │ ├── navigationHeader.test.js
│ │ │ ├── parentNavigationItem.js
│ │ │ ├── navigationHeader.js
│ │ │ ├── navigation.test.js
│ │ │ └── navigation.js
│ │ ├── __snapshots__
│ │ │ ├── app.test.js.snap
│ │ │ └── errorBoundaryComponent.test.js.snap
│ │ ├── app.js
│ │ ├── errorBoundaryComponent.js
│ │ ├── getNavigationScreens.js
│ │ ├── app.test.js
│ │ ├── errorViewComponent.js
│ │ ├── fructoseComponentWrapper.js
│ │ ├── loadingScreen.js
│ │ └── errorBoundaryComponent.test.js
│ │ ├── index.js
│ │ ├── componentLoader.js
│ │ └── componentLoader.test.js
├── test-helpers
│ ├── src
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── didWebStart.js
│ │ ├── setup.js
│ │ └── bin
│ │ │ ├── github-comment-manager.js
│ │ │ ├── run.js
│ │ │ └── github-comment-manager.test.js
│ └── bin
│ │ └── createTunnel.js
├── client
│ ├── index.js
│ ├── client.js
│ └── client.test.js
├── web
│ ├── index.ejs
│ ├── webpack.config.js
│ └── bin
│ │ └── start.js
└── common
│ └── logger.js
├── android
├── settings.gradle
├── app
│ ├── fructose.keystore
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ └── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── e2etests
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── AndroidManifest.xml
│ ├── BUCK
│ └── proguard-rules.pro
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── keystores
│ ├── debug.keystore.properties
│ └── BUCK
├── build.gradle
├── gradle.properties
└── gradlew.bat
├── e2eTests
├── app.json
├── fructose
│ ├── head.html
│ ├── webpack.config.js
│ ├── index.ios.js
│ ├── index.android.js
│ ├── index.web.js
│ ├── vendor.webpack.config.js
│ └── setup.android.sauce.js
├── scripts
│ ├── web-tests.sh
│ ├── ios-tests.sh
│ ├── android-saucelabs-tests.sh
│ └── android-tests.sh
├── example
│ ├── setup.native.hooks.js
│ ├── android.test.js
│ ├── ios.test.js
│ ├── web.test.js
│ ├── component-pages.showcase.js
│ └── component-primitives.showcase.js
└── rn-cli.config.js
├── app.json
├── index.js
├── scripts
├── install-all-deps.sh
├── tests.sh
└── ci.sh
├── setup.js
├── .buckconfig
├── .eslintignore
├── lerna.json
├── __mocks__
└── pixelmatch.js
├── .eslintrc.json
├── .gitignore
├── LICENSE
├── CONTRIBUTING.md
└── package.json
/.npmignore:
--------------------------------------------------------------------------------
1 | e2eTests/**
--------------------------------------------------------------------------------
/ios/e2eTests.app/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-midnight
--------------------------------------------------------------------------------
/index.ios.js:
--------------------------------------------------------------------------------
1 | require("./e2eTests/fructose/index.ios.js");
2 |
--------------------------------------------------------------------------------
/index.web.js:
--------------------------------------------------------------------------------
1 | require("./e2eTests/fructose/index.web.js");
2 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "react-native"
4 | ]
5 | }
--------------------------------------------------------------------------------
/index.android.js:
--------------------------------------------------------------------------------
1 | require("./e2eTests/fructose/index.android.js");
2 |
--------------------------------------------------------------------------------
/packages/server/index.html:
--------------------------------------------------------------------------------
1 |
FRUCTOSE SERVER
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'e2eTests'
2 |
3 | include ':app'
4 |
--------------------------------------------------------------------------------
/e2eTests/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "e2eTests",
3 | "displayName": "e2eTests"
4 | }
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rncomponentapp",
3 | "displayName": "rncomponentapp"
4 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import app from "./packages/app/src/index";
2 |
3 | export default app;
4 |
--------------------------------------------------------------------------------
/packages/app/src/__mocks__/componentLoader.js:
--------------------------------------------------------------------------------
1 | export default () => "componentsLoaded";
2 |
--------------------------------------------------------------------------------
/scripts/install-all-deps.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | yarn
4 | cd e2eTests
5 | rm -rf node_modules
6 | yarn
--------------------------------------------------------------------------------
/setup.js:
--------------------------------------------------------------------------------
1 | const setup = require("./packages/test-helpers/lib/index");
2 |
3 | module.exports = setup;
--------------------------------------------------------------------------------
/e2eTests/fructose/head.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/e2eTests:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/e2eTests
--------------------------------------------------------------------------------
/packages/app/src/components/__mocks__/fructoseComponent.js:
--------------------------------------------------------------------------------
1 | export default () => "FructoseComponent";
2 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Info.plist
--------------------------------------------------------------------------------
/packages/server/start.js:
--------------------------------------------------------------------------------
1 | const Server = require("./index").FructoseServer;
2 |
3 | new Server(7811).start();
4 |
--------------------------------------------------------------------------------
/android/app/fructose.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/app/fructose.keystore
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | e2eTests
3 |
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/ios/e2eTests.app/Base.lproj/LaunchScreen.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Base.lproj/LaunchScreen.nib
--------------------------------------------------------------------------------
/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XCTest:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/XCTest
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/back-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/packages/app/src/components/navigation/back-icon.png
--------------------------------------------------------------------------------
/packages/test-helpers/src/index.js:
--------------------------------------------------------------------------------
1 | import hooks from "./setup";
2 |
3 | const fructose = {};
4 | fructose.hooks = hooks;
5 |
6 | export default fructose;
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/keystores/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | key.store=debug.keystore
2 | key.alias=androiddebugkey
3 | key.store.password=android
4 | key.alias.password=android
5 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/Info.plist
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/forward-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/packages/app/src/components/navigation/forward-icon.png
--------------------------------------------------------------------------------
/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest/Info.plist
--------------------------------------------------------------------------------
/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest/e2eTestsTests:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest/e2eTestsTests
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module XCTest {
2 | umbrella header "XCTest.h"
3 | requires objc
4 | export *
5 | }
6 |
--------------------------------------------------------------------------------
/packages/app/src/components/__snapshots__/app.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`App Renders the root stack 1`] = ``;
4 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/Info.plist
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/IDEBundleInjection:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/IDEBundleInjection
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules/*
2 | **/coverage/*
3 | **/lib/*
4 | packages/test-helpers/**/*.test.js
5 | **/*.tape.js
6 | **/.fructose/components.js
7 | **/.fructose/components.test.js
8 | **/e2eTests/**
9 |
10 | **/dist/*
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "lerna": "2.0.0-rc.5",
3 | "packages": [
4 | "packages/app",
5 | "packages/server",
6 | "packages/client",
7 | "packages/test-helpers",
8 | "packages/fructose"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/Info.plist
--------------------------------------------------------------------------------
/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest.dSYM/Contents/Resources/DWARF/e2eTestsTests:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest.dSYM/Contents/Resources/DWARF/e2eTestsTests
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/Info.plist
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/XCUIRecorderService:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/XCUIRecorderService
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/xctestSymbolicator:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NewsUKArchive/fructose/HEAD/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/xctestSymbolicator
--------------------------------------------------------------------------------
/__mocks__/pixelmatch.js:
--------------------------------------------------------------------------------
1 | /* globals jest */
2 |
3 | let mockPixelMatch = (data1, data2) => {
4 | if (data1.equals(data2)) {
5 | return 0;
6 | }
7 | return 1;
8 | };
9 |
10 | mockPixelMatch = jest.fn();
11 | module.exports = mockPixelMatch;
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
6 |
--------------------------------------------------------------------------------
/e2eTests/fructose/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | const path = require("path");
3 |
4 | module.exports = {
5 | entry: [path.join(__dirname, "./index.web.js")],
6 | node: {
7 | fs: "empty",
8 | net: "empty"
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "airbnb",
4 | "prettier",
5 | "prettier/react"
6 | ],
7 | "rules": {
8 | "react/jsx-filename-extension": [1, { "extensions": [".js"] }],
9 | "import/extensions": "off"
10 | },
11 | "root": true,
12 | "env": {
13 | "jest": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/e2eTests/fructose/index.ios.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from "react-native";
2 | import fructose from "../../packages/app/src";
3 | import { getStories } from "./components"; // eslint-disable-line import/no-unresolved
4 |
5 | AppRegistry.registerComponent("e2eTests", () =>
6 | fructose(getStories, { platform: "native" })
7 | );
8 |
--------------------------------------------------------------------------------
/e2eTests/fructose/index.android.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from "react-native";
2 | import fructose from "../../packages/app/src";
3 | import { getStories } from "./components"; // eslint-disable-line import/no-unresolved
4 |
5 | AppRegistry.registerComponent("e2eTests", () =>
6 | fructose(getStories, { platform: "native" })
7 | );
8 |
--------------------------------------------------------------------------------
/e2eTests/scripts/web-tests.sh:
--------------------------------------------------------------------------------
1 | ./node_modules/.bin/rnscl --searchDir ./e2eTests/ --pattern 'example/*.showcase.js' --outputFile e2eTests/fructose/components.js
2 | node "./packages/web/bin/start" --build-dir $(pwd)/e2eTests/fructose &
3 | WEB_PID=$!
4 | ./node_modules/.bin/jest ./e2eTests/example/web.test.js --verbose --forceExit
5 | TESTS_EXIT_CODE=$?
6 | kill -9 $WEB_PID
7 | exit $TESTS_EXIT_CODE
--------------------------------------------------------------------------------
/packages/test-helpers/src/index.test.js:
--------------------------------------------------------------------------------
1 | test("index exports function as default", async () => {
2 | const fructose = require("./index").default;
3 | expect(typeof fructose.hooks.mobile.setup).toBe("function");
4 | expect(typeof fructose.hooks.mobile.cleanup).toBe("function");
5 | expect(typeof fructose.hooks.web.setup).toBe("function");
6 | expect(typeof fructose.hooks.web.cleanup).toBe("function");
7 | });
8 |
--------------------------------------------------------------------------------
/packages/client/index.js:
--------------------------------------------------------------------------------
1 | const SocketClient = require("socket.io-client");
2 | const FructoseClient = require("./client");
3 |
4 | const config = {
5 | transports: ["websocket"],
6 | query: {
7 | clientType: "tests"
8 | }
9 | };
10 |
11 | const sc = port => new SocketClient(`http://localhost:${port || 7811}`, config);
12 | const fc = port => new FructoseClient(sc(port));
13 |
14 | module.exports = fc;
15 |
--------------------------------------------------------------------------------
/e2eTests/example/setup.native.hooks.js:
--------------------------------------------------------------------------------
1 | /* globals jasmine */
2 | import fructose from "../../setup";
3 | import io from "socket.io-client";
4 |
5 | export const setup = async () => {
6 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 25000;
7 | const fructoseClient = await fructose.hooks.mobile.setup();
8 | return fructoseClient;
9 | };
10 |
11 | export const teardown = async () => {
12 | await fructose.hooks.mobile.cleanup();
13 | };
14 |
--------------------------------------------------------------------------------
/e2eTests/rn-cli.config.js:
--------------------------------------------------------------------------------
1 | const blacklist = require("metro-bundler/src/blacklist");
2 |
3 | module.exports = {
4 | getBlacklistRE() {
5 | return blacklist([
6 | /\/node_modules\/jest-haste-map\/node_modules\/.*/,
7 | /\/node_modules\/react-native\/node_modules\/fb-watchman\/.*/,
8 | /\/node_modules\/@times-components\/fructose\/node_modules\/react-native\/.*/,
9 | /\..\/.*/
10 | ]);
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/scripts/tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | yarn --npm-client=yarn --concurrency=1
4 |
5 | if yarn test:unit ; then
6 | echo "UNIT TESTS PASSED"
7 | else
8 | echo "UNIT TESTS FAILED"
9 | exit 1
10 | fi
11 |
12 | if yarn e2e:test:web ; then
13 | echo "WEB TESTS PASSED"
14 | else
15 | echo "WEB TESTS FAILED"
16 | exit 1
17 | fi
18 |
19 | if yarn e2e:test:ios ; then
20 | echo "IOS TESTS PASSED"
21 | else
22 | echo "IOS TESTS FAILED"
23 | exit 1
24 | fi
25 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/e2etests/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.e2etests;
2 |
3 | import com.facebook.react.ReactActivity;
4 |
5 | public class MainActivity extends ReactActivity {
6 |
7 | /**
8 | * Returns the name of the main component registered from JavaScript.
9 | * This is used to schedule rendering of the component.
10 | */
11 | @Override
12 | protected String getMainComponentName() {
13 | return "e2eTests";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/e2eTests/fructose/index.web.js:
--------------------------------------------------------------------------------
1 | /* globals document */
2 |
3 | import { AppRegistry, Text } from "react-native";
4 | import fructose from "../../packages/app/src";
5 | import { getStories } from "./components"; // eslint-disable-line import/no-unresolved
6 |
7 | AppRegistry.registerComponent("e2eTests", () =>
8 | fructose(getStories, { platform: "web" })
9 | );
10 | AppRegistry.runApplication("e2eTests", {
11 | rootTag: document.getElementById("react-root")
12 | });
13 |
--------------------------------------------------------------------------------
/packages/web/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React Native Web
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/scripts/ci.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | if yarn test:unit ; then
5 | echo "UNIT TESTS PASSED"
6 | else
7 | echo "UNIT TESTS FAILED"
8 | cd ../..
9 | exit 1
10 | fi
11 |
12 | cd e2eTests
13 | if yarn test:web ; then
14 | echo "E2E WEB TESTS PASSED"
15 | else
16 | echo "E2E WEB TESTS FAILED"
17 | cd ../..
18 | exit 1
19 | fi
20 |
21 | if yarn test:ios ; then
22 | echo "E2E IOS TESTS PASSED"
23 | else
24 | echo "E2E IOS TESTS FAILED"
25 | cd ../..
26 | exit 1
27 | fi
28 |
--------------------------------------------------------------------------------
/e2eTests/scripts/ios-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | xcrun simctl boot 'iPhone 7'
3 | export IPHONE=$!
4 | ./node_modules/.bin/rnscl --searchDir ./e2eTests/ --pattern 'example/*.showcase.js' --outputFile e2eTests/fructose/components.js
5 | ./node_modules/.bin/react-native start --resetCache &
6 | export PACKAGER=$!
7 | ./node_modules/.bin/react-native run-ios --no-packager
8 | LOGLEVEL=verbose node_modules/.bin/jest ./e2eTests/example/ios.test.js --verbose --forceExit
9 |
10 | kill $IPHONE
11 | kill $PACKAGER
--------------------------------------------------------------------------------
/ios/e2eTests/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/e2eTests/scripts/android-saucelabs-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | npx fructose-tunnel &
3 | yarn write-android-components
4 | pushd android
5 | ./gradlew clean
6 | ./gradlew assembleRelease
7 | popd
8 | curl -u $SAUCE_USERNAME:$SAUCE_KEY\
9 | -X POST \
10 | -H "Content-Type: application/octet-stream"\
11 | https://saucelabs.com/rest/v1/storage/tnlweb/fructose-e2e.apk?overwrite=true\
12 | --data-binary @${PWD}/android/app/build/outputs/apk/app-release.apk
13 |
14 | jest fructose/components.test.js --verbose --setupTestFrameworkScriptFile ./fructose/setup.android.sauce.js --forceExit
15 |
--------------------------------------------------------------------------------
/ios/e2eTests/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/app/src/components/app.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { createDrawerNavigator } from "react-navigation";
4 | import getNavigationScreens from "./getNavigationScreens";
5 | import Navigation from "./navigation/navigation";
6 |
7 | const App = ({ components }) => {
8 | const Root = createDrawerNavigator(getNavigationScreens(components), {
9 | contentComponent: Navigation
10 | });
11 |
12 | return ;
13 | };
14 |
15 | App.propTypes = {
16 | components: PropTypes.objectOf(PropTypes.func).isRequired
17 | };
18 |
19 | export default App;
20 |
--------------------------------------------------------------------------------
/packages/app/src/components/errorBoundaryComponent.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ErrorView from "./errorViewComponent";
3 |
4 | export default class ErrorBoundary extends React.Component {
5 | constructor() {
6 | super();
7 | this.state = {
8 | error: null
9 | };
10 | }
11 |
12 | componentDidCatch(error) {
13 | this.setState({
14 | error
15 | });
16 | }
17 |
18 | render() {
19 | if (this.state.error) {
20 | return ;
21 | }
22 |
23 | return this.props.children; //eslint-disable-line
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/e2eTests/fructose/vendor.webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const webpack = require("webpack");
3 |
4 | module.exports = {
5 | context: process.cwd(),
6 | entry: {
7 | vendor: ["prop-types", "react", "react-dom", "react-native-web"]
8 | },
9 |
10 | output: {
11 | filename: "[name].dll.js",
12 | path: path.resolve("./dist/public"),
13 | library: "[name]"
14 | },
15 |
16 | plugins: [
17 | new webpack.DllPlugin({
18 | path: path.join("./dist/public", "[name]-manifest.json"),
19 | name: "[name]",
20 | context: path.resolve(__dirname)
21 | })
22 | ]
23 | };
24 |
--------------------------------------------------------------------------------
/e2eTests/scripts/android-tests.sh:
--------------------------------------------------------------------------------
1 | emulator @fructose_device -no-boot-anim &
2 | EMU_PID=$!
3 | adb wait-for-device
4 | adb reverse tcp:8081 tcp:8081
5 | adb reverse tcp:7811 tcp:7811
6 | adb reverse tcp:4723 tcp:4723
7 | ./node_modules/.bin/rnscl --searchDir ./e2eTests/ --pattern 'example/*.showcase.js' --outputFile e2eTests/fructose/components.js
8 | ./node_modules/.bin/react-native start --resetCache &
9 | BUNDLER_PID=$!
10 | ./node_modules/.bin/react-native run-android --no-packager
11 | LOGLEVEL=verbose node_modules/.bin/jest ./e2eTests/example/android.test.js --verbose --forceExit
12 | kill -9 $EMU_PID
13 | kill -9 $BUNDLER_PID
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildAliasOf
6 | XCTest
7 | BuildVersion
8 | 4
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 12124
13 | ProjectName
14 | XCTest_Sim
15 | SourceVersion
16 | 12124000000000000
17 |
18 |
19 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/parentNavigationItem.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe beforeEach it expect */
2 |
3 | import React from "react";
4 | import { configure, shallow } from "enzyme";
5 | import Adapter from "enzyme-adapter-react-16";
6 | import ParentNavigationItem from "./parentNavigationItem";
7 |
8 | configure({
9 | adapter: new Adapter()
10 | });
11 |
12 | describe("Parent Navigation Header", () => {
13 | let app;
14 |
15 | it("Renders without back icon", () => {
16 | app = shallow(
17 | {}} />
18 | );
19 | expect(app).toMatchSnapshot();
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/__snapshots__/navigation.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Navigation renders when is child menu 1`] = `
4 | Array [
5 | ,
10 | ,
13 | ]
14 | `;
15 |
16 | exports[`Navigation renders when is parent menu 1`] = `
17 | Array [
18 | ,
23 | ,
26 | ]
27 | `;
28 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildAliasOf
6 | XCTest
7 | BuildVersion
8 | 4
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 1
13 | ProjectName
14 | XCTest_Sim
15 | SourceVersion
16 | 12124000000000000
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildAliasOf
6 | XCTest
7 | BuildVersion
8 | 4
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 1
13 | ProjectName
14 | XCTest_Sim
15 | SourceVersion
16 | 12124000000000000
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildAliasOf
6 | IDEBundleInjection
7 | BuildVersion
8 | 49
9 | CFBundleShortVersionString
10 | 5.0
11 | CFBundleVersion
12 | 12002
13 | ProjectName
14 | IDEBundleInjection_Sim
15 | SourceVersion
16 | 12002000000000000
17 |
18 |
19 |
--------------------------------------------------------------------------------
/packages/app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import App from "./components/app";
3 | import componentLoader from "./componentLoader";
4 |
5 | const defaultPlatform = "native";
6 |
7 | export default (componentsToLoad, config) => () => {
8 | // disable red + yellow pop ups and allow our own error component to render
9 | console._errorOriginal = console.error.bind(console); // eslint-disable-line
10 | console.error = () => {}; // eslint-disable-line
11 | console.disableYellowBox = true; // eslint-disable-line
12 |
13 | const platform = config.platform || defaultPlatform;
14 | const components = componentLoader(componentsToLoad, platform);
15 |
16 | return ;
17 | };
18 |
--------------------------------------------------------------------------------
/packages/app/src/components/getNavigationScreens.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ErrorBoundary from "./errorBoundaryComponent";
3 | import FructoseComponentWrapper from "./fructoseComponentWrapper";
4 | import LoadingScreen from "./loadingScreen";
5 |
6 | export default componentsToLoad => {
7 | const navigationList = {
8 | Home: {
9 | screen: LoadingScreen
10 | }
11 | };
12 |
13 | Object.keys(componentsToLoad).forEach(component => {
14 | navigationList[component] = {
15 | screen: () => (
16 |
17 |
18 |
19 | )
20 | };
21 | });
22 |
23 | return navigationList;
24 | };
25 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$rootDir/../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/app/src/components/app.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe beforeEach it expect */
2 |
3 | import React from "react";
4 | import { View } from "react-native";
5 | import { configure, shallow } from "enzyme";
6 | import Adapter from "enzyme-adapter-react-16";
7 | import App from "./app";
8 |
9 | configure({ adapter: new Adapter() });
10 |
11 | describe("App", () => {
12 | let app;
13 | let components;
14 |
15 | beforeEach(() => {
16 | components = {
17 | component1: () => ,
18 | component2: () => ,
19 | component3: () =>
20 | };
21 | });
22 |
23 | it("Renders the root stack", () => {
24 | app = shallow();
25 |
26 | expect(app).toMatchSnapshot();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/e2eTests/example/android.test.js:
--------------------------------------------------------------------------------
1 | import showcases from "./component-pages.showcase";
2 | import { setup, teardown } from "./setup.native.hooks";
3 |
4 | describe("Android example tests", () => {
5 | let fructoseClient;
6 |
7 | beforeAll(async () => {
8 | fructoseClient = await setup();
9 | }, 18000);
10 |
11 | it("loads all expected components ", async () => {
12 | expect.assertions(showcases.children.length);
13 |
14 | for (let i = 0; i < showcases.children.length; i++) {
15 | const result = await fructoseClient.loadComponent(
16 | `${showcases.name}:${showcases.children[i].name}`
17 | );
18 | expect(result).toBe("component loaded");
19 | }
20 | });
21 |
22 | afterAll(() => {
23 | teardown();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/e2eTests/example/ios.test.js:
--------------------------------------------------------------------------------
1 | import io from "socket.io-client";
2 | import showcases from "./component-pages.showcase";
3 | import { setup, teardown } from "./setup.native.hooks";
4 |
5 | describe("IOS example tests", () => {
6 | let fructoseClient;
7 |
8 | beforeAll(async () => {
9 | fructoseClient = await setup();
10 | }, 18000);
11 |
12 | it("loads all expected components ", async () => {
13 | expect.assertions(showcases.children.length);
14 |
15 | for (let i = 0; i < showcases.children.length; i++) {
16 | const result = await fructoseClient.loadComponent(
17 | `${showcases.name}:${showcases.children[i].name}`
18 | );
19 | expect(result).toBe("component loaded");
20 | }
21 | });
22 |
23 | afterAll(() => {
24 | teardown();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/ios/e2eTests/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/packages/common/logger.js:
--------------------------------------------------------------------------------
1 | const log = require("npmlog");
2 |
3 | log.level = process.env.LOGLEVEL || "info";
4 | log.stream = process.stdout;
5 | log.enableColor();
6 | log.info("logger", `Log level is ${log.level}`);
7 |
8 | module.exports = {
9 | info: (fileName, textToLog) => {
10 | log.stream = process.stdout;
11 | log.prefixStyle = { fg: "green", bg: "black" };
12 | log.info(`[${fileName}] :`, textToLog);
13 | },
14 | verbose: (fileName, textToLog) => {
15 | log.stream = process.stdout;
16 | log.prefixStyle = { fg: "blue" };
17 | log.verbose(`[${fileName}] :`, textToLog);
18 | },
19 | error: (fileName, textToError) => {
20 | log.stream = process.stdout;
21 | log.prefixStyle = { fg: "red" };
22 | log.error(`[${fileName}] :`, textToError);
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest.dSYM/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleIdentifier
8 | com.apple.xcode.dsym.org.reactjs.native.example.e2eTestsTests
9 | CFBundleInfoDictionaryVersion
10 | 6.0
11 | CFBundlePackageType
12 | dSYM
13 | CFBundleSignature
14 | ????
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleVersion
18 | 1
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ios/e2eTestsTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/packages/test-helpers/bin/createTunnel.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require("fs");
4 | const ngrok = require("ngrok");
5 | const path = require("path");
6 | const log = require("../../common/logger");
7 |
8 | function serverUrlString(url) {
9 | const json = {
10 | "server-url": url
11 | };
12 | return `${JSON.stringify(json)}\n`;
13 | }
14 |
15 | function writeProperties(contents) {
16 | fs.writeFile(
17 | path.join(__dirname, "./../../app/src/properties.json"),
18 | contents,
19 | err => {
20 | if (err) throw err;
21 | log.info("createTunnel", "Properties file updated");
22 | }
23 | );
24 | }
25 |
26 | if (process.env.LOCAL) {
27 | writeProperties(serverUrlString("http://localhost:7811"));
28 | } else {
29 | ngrok.connect(7811, (err, url) => {
30 | if (err) throw err;
31 | writeProperties(serverUrlString(url));
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestErrors.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | /*!
8 | * @const XCTestErrorDomain
9 | * Domain for errors provided by the XCTest framework.
10 | */
11 | XCT_EXPORT NSString *const XCTestErrorDomain;
12 |
13 | /*!
14 | * @typedef XCTestErrorCode
15 | * Error codes used with errors in the XCTestErrorDomain.
16 | *
17 | * @constant XCTestErrorCodeTimeoutWhileWaiting Indicates that a call to -waitForExpectationsWithTimeout:handler: timed out.
18 | * @constant XCTestErrorCodeFailureWhileWaiting Indicates that a failure assertion was raised while waiting in -waitForExpectationsWithTimeout:handler:.
19 | */
20 | typedef NS_ENUM(NSInteger, XCTestErrorCode) {
21 | XCTestErrorCodeTimeoutWhileWaiting,
22 | XCTestErrorCodeFailureWhileWaiting,
23 | };
24 |
25 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/navigationHeader.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe beforeEach it expect */
2 |
3 | import React from "react";
4 | import { configure, shallow } from "enzyme";
5 | import Adapter from "enzyme-adapter-react-16";
6 | import NavigationHeader from "./navigationHeader";
7 |
8 | configure({
9 | adapter: new Adapter()
10 | });
11 |
12 | describe("Navigation Header", () => {
13 | let app;
14 |
15 | it("Renders without back icon", () => {
16 | app = shallow(
17 | {}}
19 | isParentMenu={() => true}
20 | />
21 | );
22 | expect(app).toMatchSnapshot();
23 | });
24 |
25 | it("Renders with back icon", () => {
26 | app = shallow(
27 | {}}
29 | isParentMenu={() => false}
30 | />
31 | );
32 | expect(app).toMatchSnapshot();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/e2eTests/example/web.test.js:
--------------------------------------------------------------------------------
1 | import io from "socket.io-client";
2 | import showcases from "./component-pages.showcase";
3 | import fructose from "./../../setup";
4 |
5 | describe("Web example tests", () => {
6 | let fructoseClient;
7 | let chrome;
8 |
9 | beforeAll(async () => {
10 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 25000;
11 |
12 | const { client, chromeless } = await fructose.hooks.web.setup(3000, 60000);
13 | fructoseClient = client;
14 |
15 | //for examples benefit
16 | chrome = chromeless;
17 | }, 60000);
18 |
19 | it("loads all expected components ", async () => {
20 | expect.assertions(showcases.children.length);
21 |
22 | for (let i = 0; i < showcases.children.length; i++) {
23 | const result = await fructoseClient.loadComponent(
24 | `${showcases.name}:${showcases.children[i].name}`
25 | );
26 |
27 | expect(result).toBe("component loaded");
28 | }
29 | });
30 |
31 | afterAll(async () => {
32 | await fructose.hooks.web.cleanup();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/packages/app/src/components/errorViewComponent.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, StatusBar } from "react-native";
3 | import PropTypes from "prop-types";
4 |
5 | const styles = StyleSheet.create({
6 | errorContainer: {
7 | backgroundColor: "#B20000",
8 | height: "100%"
9 | },
10 | errorHeader: {
11 | fontWeight: "bold",
12 | fontSize: 24,
13 | color: "white",
14 | textAlign: "center"
15 | },
16 | stackTrace: {
17 | color: "white",
18 | fontSize: 16
19 | }
20 | });
21 |
22 | const ErrorState = props => (
23 |
24 |
25 | Exception Found
26 | {props.error.message}
27 |
28 | );
29 |
30 | ErrorState.propTypes = {
31 | error: PropTypes.shape({
32 | message: PropTypes.string,
33 | stack: PropTypes.string
34 | })
35 | };
36 |
37 | ErrorState.defaultProps = {
38 | error: {}
39 | };
40 |
41 | export default ErrorState;
42 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useDeprecatedNdk=true
21 | STORE_FILE=fructose.keystore
22 | RELEASE_KEY_ALIAS=fructose
23 | STORE_PASSWORD=fructose
24 | RELEASE_KEY_PASSWORD=fructose
25 |
--------------------------------------------------------------------------------
/packages/app/src/components/fructoseComponentWrapper.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { StyleSheet, View, StatusBar, Text } from "react-native";
4 |
5 | const styles = StyleSheet.create({
6 | container: {
7 | backgroundColor: "white",
8 | height: "100%",
9 | width: "100%"
10 | }
11 | });
12 |
13 | const knobs = {
14 | select: () => {},
15 | color: () => {},
16 | selectV2: () => {},
17 | text: () => {},
18 | number: () => {},
19 | boolean: () => {},
20 | array: () => {},
21 | radio: () => {},
22 | date: () => {},
23 | button: () => {},
24 | e2eTestDontDelete: () => YAY I RENDERED
25 | };
26 |
27 | const actions = {
28 | action: () => {},
29 | decorateAction: () => () => {}
30 | };
31 |
32 | const FructoseComponentWrapper = ({ component }) => (
33 |
34 |
35 | {component(knobs, actions)}
36 |
37 | );
38 |
39 | FructoseComponentWrapper.propTypes = {
40 | component: PropTypes.func.isRequired
41 | };
42 |
43 | export default FructoseComponentWrapper;
44 |
--------------------------------------------------------------------------------
/packages/app/src/components/loadingScreen.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, Text, View } from "react-native";
3 | import { version } from "../../../../package.json";
4 |
5 | const styles = StyleSheet.create({
6 | header: {
7 | color: "white",
8 | fontSize: 40,
9 | textAlign: "center"
10 | },
11 | version: {
12 | padding: 10,
13 | color: "white",
14 | fontSize: 20,
15 | textAlign: "left"
16 | },
17 | text: {
18 | paddingTop: 10,
19 | color: "white",
20 | fontSize: 16,
21 | textAlign: "center"
22 | },
23 | view: {
24 | backgroundColor: "lightpink",
25 | height: "100%",
26 | width: "100%",
27 | flex: 1,
28 | flexDirection: "column",
29 | justifyContent: "space-between"
30 | }
31 | });
32 |
33 | const LoadingScreen = () => (
34 |
35 |
36 | Brought to you by {"\n"} The Times Tooling Team
37 |
38 | 🛠 FRUCTOSE 🛠
39 | Version: {version}
40 |
41 | );
42 |
43 | export default LoadingScreen;
44 |
--------------------------------------------------------------------------------
/packages/app/src/components/errorBoundaryComponent.test.js:
--------------------------------------------------------------------------------
1 | /* globals it expect */
2 |
3 | import React from "react";
4 | import { Text } from "react-native";
5 | import { EventEmitter } from "events";
6 | import renderer from "react-test-renderer";
7 |
8 | import ErrorBoundary from "./errorBoundaryComponent";
9 |
10 | const ThrowAnError = () => {lol}; // eslint-disable-line
11 |
12 | describe("Error Boundary", () => {
13 | it("It renders the error View when error is triggered", () => {
14 | const wrapper = renderer
15 | .create(
16 |
17 |
18 |
19 | )
20 | .toJSON();
21 |
22 | expect(wrapper).toMatchSnapshot();
23 | });
24 |
25 | it("it render a component when there is no error", () => {
26 | const wrapper = renderer
27 | .create(
28 |
29 | Hey I rendered
30 |
31 | )
32 | .toJSON();
33 |
34 | expect(wrapper).toMatchSnapshot();
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/e2etests/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.e2etests;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.shell.MainReactPackage;
9 | import com.facebook.soloader.SoLoader;
10 |
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | public class MainApplication extends Application implements ReactApplication {
15 |
16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | return Arrays.asList(
25 | new MainReactPackage()
26 | );
27 | }
28 | };
29 |
30 | @Override
31 | public ReactNativeHost getReactNativeHost() {
32 | return mReactNativeHost;
33 | }
34 |
35 | @Override
36 | public void onCreate() {
37 | super.onCreate();
38 | SoLoader.init(this, /* native exopackage */ false);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/test-helpers/src/didWebStart.js:
--------------------------------------------------------------------------------
1 | import request from "request";
2 | import EventEmitter from "events";
3 |
4 | const isWebStarted = port =>
5 | new Promise(resolve => {
6 | request(
7 | {
8 | uri: `http://localhost:${port}`,
9 | timeout: 1000
10 | },
11 | error => {
12 | if (error) {
13 | resolve(false);
14 | } else {
15 | resolve(true);
16 | }
17 | }
18 | );
19 | });
20 |
21 | export default (port, timeout) =>
22 | new Promise(resolve => {
23 | const intervalLength = 1100;
24 | let intervals = timeout / intervalLength;
25 | const event = new EventEmitter();
26 | event.on("taken", taken => {
27 | resolve(taken);
28 | });
29 | let taken;
30 | const interval = setInterval(async () => {
31 | intervals -= 1;
32 | taken = await isWebStarted(port, timeout);
33 | if (taken) {
34 | event.emit("taken", true);
35 | clearInterval(interval);
36 | }
37 | if (!taken && intervals === 0) {
38 | event.emit("taken", false);
39 | clearInterval(interval);
40 | }
41 | }, intervalLength);
42 | });
43 |
--------------------------------------------------------------------------------
/packages/app/src/components/__snapshots__/errorBoundaryComponent.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Error Boundary It renders the error View when error is triggered 1`] = `
4 |
12 |
25 | Exception Found
26 |
27 |
38 | lol is not defined
39 |
40 |
41 | `;
42 |
43 | exports[`Error Boundary it render a component when there is no error 1`] = `
44 |
49 | Hey I rendered
50 |
51 | `;
52 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/parentNavigationItem.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { TouchableOpacity, View, Text, StyleSheet, Image } from "react-native";
3 | import PropTypes from "prop-types";
4 | import forwardIcon from "./forward-icon.png";
5 |
6 | const styles = StyleSheet.create({
7 | menuHeaderText: {
8 | color: "gray",
9 | fontSize: 14,
10 | fontWeight: "bold"
11 | },
12 | button: {
13 | paddingTop: 21,
14 | paddingBottom: 16,
15 | paddingLeft: 15,
16 | paddingRight: 10
17 | },
18 | image: {
19 | width: 20,
20 | height: 20
21 | }
22 | });
23 |
24 | const ParentNavigationItem = ({ label, onPress }) => (
25 |
26 |
32 | {label}
33 |
34 |
35 |
36 | );
37 |
38 | ParentNavigationItem.propTypes = {
39 | label: PropTypes.string.isRequired,
40 | onPress: PropTypes.func.isRequired
41 | };
42 |
43 | export default ParentNavigationItem;
44 |
--------------------------------------------------------------------------------
/packages/app/src/componentLoader.js:
--------------------------------------------------------------------------------
1 | const isValidShowcase = parent => {
2 | if (!parent) return false;
3 | if (!parent.default) return false;
4 | if (!parent.default.children) return false;
5 | return true;
6 | };
7 |
8 | const filterShowcases = (showcases, platform) =>
9 | showcases.children
10 | .filter(showcase => showcase.type === "story")
11 | .filter(showcase => !showcase.hasExternalDeps)
12 | .filter(showcase => {
13 | if (showcase.platform) {
14 | return showcase.platform.includes(platform);
15 | }
16 | return showcase;
17 | });
18 |
19 | export default (loadComponents, platform) => {
20 | const componentsStore = {};
21 | const components = loadComponents();
22 |
23 | if (components) {
24 | components.forEach(parent => {
25 | if (isValidShowcase(parent)) {
26 | const showcases = parent.default;
27 | const filteredShowcases = filterShowcases(showcases, platform);
28 |
29 | filteredShowcases.forEach(showcase => {
30 | const showCaseName = `${showcases.name}:${
31 | showcase.name
32 | }`.toLowerCase();
33 | componentsStore[showCaseName] = showcase.component;
34 | });
35 | }
36 | });
37 | }
38 | return componentsStore;
39 | };
40 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/__snapshots__/parentNavigationItem.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Parent Navigation Header Renders without back icon 1`] = `
4 |
16 |
24 |
36 |
37 | label to render
38 |
39 |
52 |
53 |
54 | `;
55 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUISiriService.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | #if XCT_UI_TESTING_AVAILABLE && TARGET_OS_IOS
10 |
11 | /*!
12 | * @class XCUISiriService
13 | * Represents a device's Siri interface and allows issuing textual queries
14 | * and producing element queries for UI shown by Siri.
15 | */
16 | NS_CLASS_AVAILABLE_IOS(10_3)
17 | @interface XCUISiriService : NSObject
18 |
19 | + (instancetype)new NS_UNAVAILABLE;
20 | - (instancetype)init NS_UNAVAILABLE;
21 |
22 | /*!
23 | * Provides debugging information about the element representing the root of the Siri UI.
24 | * @seealso XCUIElement
25 | */
26 | @property (readonly, copy) NSString *debugDescription;
27 |
28 | /*!
29 | * Presents the Siri UI, if it is not currently active, and accepts a string
30 | * which is then processed as if it were recognized speech.
31 | *
32 | * @param text The string to pass to Siri for processing.
33 | */
34 | - (void)activateWithVoiceRecognitionText:(NSString *)text NS_SWIFT_NAME(activate(voiceRecognitionText:));
35 |
36 | @end
37 |
38 | @interface XCUISiriService (XCUIElementTypeQueryProvider)
39 | @end
40 |
41 | #endif
42 |
43 | NS_ASSUME_NONNULL_END
44 |
--------------------------------------------------------------------------------
/packages/client/client.js:
--------------------------------------------------------------------------------
1 | const log = require("../common/logger");
2 |
3 | class FructoseClient {
4 | constructor(socketClient) {
5 | this.socket = socketClient;
6 | }
7 |
8 | waitForApp() {
9 | return new Promise(resolve => {
10 | log.verbose("fructose Client", "waiting for app to boot");
11 | this.socket.on("fructose-app-ready", () => {
12 | log.info("fructose Client", "fructose app Loaded 💯");
13 | resolve();
14 | });
15 | });
16 | }
17 |
18 | getLoadedComponents() {
19 | return new Promise(resolve => {
20 | this.socket.on("send-loaded-app-components", componentList => {
21 | resolve(componentList);
22 | });
23 | log.verbose("fructose Client", "getting loaded app components");
24 | this.socket.emit("get-loaded-app-components");
25 | });
26 | }
27 |
28 | loadComponent(component) {
29 | return new Promise(resolve => {
30 | this.socket.on("component-loaded-in-app", () => {
31 | log.info("fructose client", `component loaded: ${component}`);
32 | this.socket.removeListener("component-loaded-in-app");
33 | resolve("component loaded");
34 | });
35 |
36 | log.info("fructose client", `loading component: ${component}`);
37 | this.socket.emit("load-component-in-app", component);
38 | });
39 | }
40 |
41 | disconnect() {
42 | this.socket.disconnect();
43 | log.info("fructose client", "client terminated");
44 | }
45 | }
46 |
47 | module.exports = FructoseClient;
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # vscode
34 | €
35 | .vscode
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # BUCK
44 | buck-out/
45 | \.buckd/
46 |
47 | # fastlane
48 | #
49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
50 | # screenshots whenever they are needed.
51 | # For more information about the recommended setup visit:
52 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
53 |
54 | fastlane/report.xml
55 | fastlane/Preview.html
56 | fastlane/screenshots
57 |
58 | #coverage
59 | **/coverage
60 | .nyc_output/**
61 | sandbox
62 |
63 | # babeled stuff
64 | packages/test-helpers/lib/**
65 |
66 | # ejs template
67 | packages/web/templates/**
68 |
69 | **/.fructose/components.js
70 | **/.fructose/components.test.js
71 | **/fructose/components.js
72 | **/fructose/components.test.js
73 |
74 | !dist
75 | !dist/public
76 | dist/public/**
77 | !dist/public/react-logo.png
78 | packages/web/dist/*
79 |
80 | **/__snapshots__/*/tmp
81 | **/vendor-dev
82 | **/vendor
83 |
--------------------------------------------------------------------------------
/ios/e2eTests/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "AppDelegate.h"
11 |
12 | #import
13 | #import
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | NSURL *jsCodeLocation;
20 |
21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
22 |
23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
24 | moduleName:@"e2eTests"
25 | initialProperties:nil
26 | launchOptions:launchOptions];
27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
28 |
29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
30 | UIViewController *rootViewController = [UIViewController new];
31 | rootViewController.view = rootView;
32 | self.window.rootViewController = rootViewController;
33 | [self.window makeKeyAndVisible];
34 | return YES;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/e2eTests/fructose/setup.android.sauce.js:
--------------------------------------------------------------------------------
1 | /* globals beforeAll afterAll jasmine */
2 | import fructose from "@times-components/fructose/setup";
3 | import wd from "wd";
4 |
5 | const SAUCE_USERNAME = process.env.SAUCE_USERNAME;
6 | const SAUCE_KEY = process.env.SAUCE_KEY;
7 |
8 | if (!SAUCE_KEY || !SAUCE_USERNAME) {
9 | throw new Error(
10 | `
11 | Sauce username or key is undefined.
12 | Please set the Environment Variables SAUCE_KEY and SAUCE_USERNAME
13 | `
14 | );
15 | }
16 |
17 | global.asserter = wd.asserters;
18 | const driver = wd.promiseChainRemote(
19 | `https://${SAUCE_USERNAME}:${SAUCE_KEY}@ondemand.saucelabs.com:443/wd/hub`
20 | );
21 |
22 | beforeAll(async () => {
23 | await fructose.hooks.mobile.setup();
24 |
25 | const options = {
26 | desiredCapabilities: {
27 | appiumVersion: "1.6.5",
28 | platformName: "Android",
29 | browserName: "",
30 | deviceName: "Android GoogleAPI Emulator",
31 | platformVersion: "7.1",
32 | app: "sauce-storage:fructose-e2e.apk",
33 | autoGrantPermissions: true
34 | },
35 | host: "localhost",
36 | port: 4723
37 | };
38 |
39 | global.driver = driver;
40 | await driver.init(options.desiredCapabilities).setImplicitWaitTimeout(300000);
41 |
42 | await global.driver.waitForElementsByXPath(
43 | '//*[@text="Fructose"]',
44 | global.asserter.isDisplayed,
45 | 1800000
46 | );
47 |
48 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000000;
49 | }, 1800000);
50 |
51 | afterAll(async () => {
52 | await fructose.hooks.mobile.cleanup();
53 | });
54 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/navigationHeader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, Image, StyleSheet, TouchableOpacity } from "react-native";
3 | import PropTypes from "prop-types";
4 | import backIcon from "./back-icon.png";
5 |
6 | const styles = StyleSheet.create({
7 | menuHeaderText: {
8 | color: "gray",
9 | textAlign: "center",
10 | fontSize: 20
11 | },
12 | menuHeader: {
13 | flexDirection: "row",
14 | backgroundColor: "skyblue",
15 | paddingVertical: 28,
16 | paddingLeft: 17,
17 | alignItems: "center"
18 | },
19 | menuSeparator: {
20 | backgroundColor: "gray",
21 | height: StyleSheet.hairlineWidth,
22 | width: "100%"
23 | },
24 | image: {
25 | width: 40,
26 | height: 40
27 | }
28 | });
29 |
30 | const MenuSeparator = () => ;
31 |
32 | const renderImage = isParentMenu =>
33 | isParentMenu ? (
34 |
35 | ) : (
36 |
37 | );
38 |
39 | const NavigationHeader = ({ navigateToCallback, isParentMenu }) => (
40 | navigateToCallback()}>
41 |
42 | {renderImage(isParentMenu())}
43 | Component List
44 |
45 |
46 |
47 | );
48 |
49 | NavigationHeader.propTypes = {
50 | navigateToCallback: PropTypes.func.isRequired,
51 | isParentMenu: PropTypes.func.isRequired
52 | };
53 |
54 | export default NavigationHeader;
55 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2017, News UK & Ireland Ltd
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTNSPredicateExpectation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /*!
12 | * @class XCTNSPredicateExpectation
13 | * Expectation subclass for waiting on a condition defined by an NSPredicate and an object.
14 | */
15 | @interface XCTNSPredicateExpectation : XCTestExpectation {
16 | #ifndef __OBJC2__
17 | @private
18 | id _internal;
19 | #endif
20 | }
21 |
22 | - (instancetype)init NS_UNAVAILABLE;
23 | - (instancetype)initWithDescription:(NSString *)expectationDescription NS_UNAVAILABLE;
24 |
25 | /*!
26 | * @method -initWithPredicate:object:
27 | * Initializes an expectation that waits for a predicate to evaluate as true with the provided object.
28 | */
29 | - (instancetype)initWithPredicate:(NSPredicate *)predicate object:(nullable id)object NS_DESIGNATED_INITIALIZER;
30 |
31 | /*!
32 | * @property predicate
33 | * Returns the predicate used by the expectation.
34 | */
35 | @property (readonly, copy) NSPredicate *predicate;
36 |
37 | /*!
38 | * @property object
39 | * Returns the object against which the predicate is evaluated.
40 | */
41 | @property (nullable, readonly, strong) id object;
42 |
43 | /*!
44 | * @property handler
45 | * Allows the caller to install a special handler to do custom evaluation of predicate and its object.
46 | */
47 | @property (nullable, copy) XCPredicateExpectationHandler handler;
48 |
49 | @end
50 |
51 | NS_ASSUME_NONNULL_END
52 |
--------------------------------------------------------------------------------
/packages/web/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const HtmlWebpackPlugin = require("html-webpack-plugin");
3 | const webpack = require("webpack");
4 |
5 | const alias = {
6 | "react-native": "react-native-web"
7 | };
8 | const extensions = [".web.js", ".js", ".jsx", ".mjs"];
9 | const mode = "production";
10 |
11 | const babelConfig = [
12 | {
13 | test: /\.js$/,
14 | use: {
15 | loader: "babel-loader",
16 | options: {
17 | cacheDirectory: true,
18 | presets: ["react-native"],
19 | plugins: ["transform-regenerator", "react-native-web"]
20 | }
21 | }
22 | },
23 | {
24 | test: /\.ttf$/,
25 | loader: "url-loader",
26 | include: path.resolve(
27 | __dirname,
28 | "../node_modules/react-native-vector-icons"
29 | )
30 | },
31 | {
32 | include: /node_modules/,
33 | test: /\.mjs$/,
34 | type: "javascript/auto"
35 | },
36 | {
37 | test: /\.(gif|jpe?g|png|svg)$/,
38 | loader: "url-loader",
39 | query: {
40 | name: "images/[name]-[hash:16].[ext]"
41 | }
42 | }
43 | ];
44 |
45 | module.exports = {
46 | mode,
47 | entry: ["babel-polyfill"],
48 | module: {
49 | rules: babelConfig
50 | },
51 | plugins: [
52 | new HtmlWebpackPlugin({
53 | filename: "index.html",
54 | template: path.join(__dirname, "./index.ejs")
55 | }),
56 | new webpack.DefinePlugin({
57 | __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || "true"))
58 | })
59 | ],
60 | output: {
61 | filename: "test.bundle.js",
62 | path: path.resolve(__dirname, "./dist")
63 | },
64 | resolve: {
65 | alias,
66 | extensions
67 | }
68 | };
69 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIRemote.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | NS_ASSUME_NONNULL_BEGIN
9 |
10 | #if XCT_UI_TESTING_AVAILABLE
11 |
12 | /*!
13 | * @enum XCUIRemoteButton
14 | *
15 | * A button on a physical remote control.
16 | */
17 | typedef NS_ENUM(NSUInteger, XCUIRemoteButton) {
18 | XCUIRemoteButtonUp = 0,
19 | XCUIRemoteButtonDown = 1,
20 | XCUIRemoteButtonLeft = 2,
21 | XCUIRemoteButtonRight = 3,
22 |
23 | XCUIRemoteButtonSelect = 4,
24 | XCUIRemoteButtonMenu = 5,
25 | XCUIRemoteButtonPlayPause = 6,
26 | };
27 |
28 | #if TARGET_OS_TV
29 |
30 | /*!
31 | * @class XCUIRemote
32 | *
33 | * Simulates interaction with a physical remote control.
34 | */
35 | NS_CLASS_AVAILABLE_IOS(9_0)
36 | @interface XCUIRemote : NSObject
37 |
38 | /*!
39 | * The simulated physical remote control.
40 | */
41 | + (instancetype)sharedRemote;
42 |
43 | /*!
44 | * Sends a momentary press of a button on a physical remote control.
45 | *
46 | * @param remoteButton
47 | * The button on the physical remote control for which to synthesize a press.
48 | */
49 | - (void)pressButton:(XCUIRemoteButton)remoteButton;
50 |
51 | /*!
52 | * Sends a press and hold of a button on a physical remote control, holding for the specified duration.
53 | *
54 | * @param remoteButton
55 | * The button on the physical remote control for which to synthesize a press.
56 | *
57 | * @param duration
58 | * Duration in seconds.
59 | */
60 | - (void)pressButton:(XCUIRemoteButton)remoteButton forDuration:(NSTimeInterval)duration;
61 |
62 | @end
63 |
64 | #endif
65 |
66 | #endif
67 |
68 | NS_ASSUME_NONNULL_END
69 |
--------------------------------------------------------------------------------
/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
15 | lib_deps.append(':' + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "com.e2etests",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.e2etests",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/ios/e2eTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | e2eTests
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UIViewControllerBasedStatusBarAppearance
40 |
41 | NSLocationWhenInUseUsageDescription
42 |
43 | NSAppTransportSecurity
44 |
45 |
46 | NSExceptionDomains
47 |
48 | localhost
49 |
50 | NSExceptionAllowsInsecureHTTPLoads
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/packages/test-helpers/src/setup.js:
--------------------------------------------------------------------------------
1 | import "babel-polyfill";
2 | import { Chromeless } from "chromeless";
3 | import { FructoseServer } from "../../server";
4 | import log from "../../common/logger";
5 | import checkIfWebStarted from "./didWebStart";
6 | import fructoseClient from "../../client";
7 |
8 | const fructosePort = 7811;
9 | let server;
10 | let client;
11 | let chromeless;
12 |
13 | const mobileHooks = () => {
14 | const setup = async () => {
15 | server = new FructoseServer(fructosePort);
16 |
17 | await server
18 | .start()
19 | .then(() =>
20 | log.verbose(
21 | "setup",
22 | `fructose server started on port : ${fructosePort}`
23 | )
24 | );
25 |
26 | client = fructoseClient(fructosePort);
27 | await client.waitForApp();
28 | return client;
29 | };
30 |
31 | const cleanup = () => {
32 | client.disconnect();
33 | server.close();
34 | };
35 |
36 | return { setup, cleanup };
37 | };
38 |
39 | const webHooks = () => {
40 | const setup = async (port, timeout) => {
41 | const appStarted = await checkIfWebStarted(port, timeout);
42 | if (!appStarted) {
43 | throw new Error(
44 | "App did not start. Run 'fructose-web --build-dir path/to/dir' first"
45 | );
46 | }
47 | server = new FructoseServer(fructosePort);
48 |
49 | await server.start();
50 |
51 | client = fructoseClient(fructosePort);
52 |
53 | chromeless = new Chromeless()
54 | .goto("http://localhost:3000")
55 | .exists("[data-testid='fructose']");
56 |
57 | await client.waitForApp();
58 | return { client, chromeless };
59 | };
60 |
61 | const cleanup = async () => {
62 | await chromeless.end();
63 | client.disconnect();
64 | server.close();
65 | };
66 |
67 | return { setup, cleanup };
68 | };
69 | export default {
70 | web: webHooks(),
71 | mobile: mobileHooks()
72 | };
73 |
--------------------------------------------------------------------------------
/packages/test-helpers/src/bin/github-comment-manager.js:
--------------------------------------------------------------------------------
1 | import { read, remove, create } from "github-comment-manager";
2 |
3 | require("babel-polyfill");
4 |
5 | const commentHeader =
6 | "If you use Expo, view our components by scanning this qr code:
";
7 |
8 | const filterExpoComments = comments =>
9 | JSON.parse(comments)
10 | .filter(({ body }) => body.includes(commentHeader))
11 | .map(({ id }) => id);
12 |
13 | const getExpoComments = (account, token, pullRequest, repository) =>
14 | read
15 | .comments({
16 | account,
17 | token,
18 | pullRequest,
19 | repository
20 | })
21 | .then(comments => filterExpoComments(comments));
22 |
23 | const deleteComment = (commentId, account, token, repository) =>
24 | remove.comment({
25 | account,
26 | token,
27 | repository,
28 | commentId
29 | });
30 |
31 | const deleteCommentsFromList = (comments, account, token, repository) =>
32 | Promise.all(
33 | comments.map(commentId =>
34 | deleteComment(commentId, account, token, repository)
35 | )
36 | ).then(() => comments.length);
37 |
38 | const createNewExpoComment = (
39 | account,
40 | token,
41 | documentPath,
42 | pullRequest,
43 | repository
44 | ) =>
45 | create.comment({
46 | account,
47 | token,
48 | repository,
49 | comment: `${commentHeader}
This has been made possible through [Fructose](https://github.com/newsuk/fructose) `,
50 | pullRequest
51 | });
52 |
53 | const deleteAllExpoComments = async (
54 | account,
55 | token,
56 | pullRequest,
57 | repository
58 | ) => {
59 | const comments = await getExpoComments(
60 | account,
61 | token,
62 | pullRequest,
63 | repository
64 | );
65 | return deleteCommentsFromList(comments, account, token, repository);
66 | };
67 |
68 | export default {
69 | deleteAllExpoComments,
70 | createNewExpoComment
71 | };
72 |
--------------------------------------------------------------------------------
/packages/test-helpers/src/bin/run.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import program from "commander";
4 | import githubCommentManager from "./github-comment-manager";
5 | import log from "../../../common/logger";
6 |
7 | program
8 | .command("publish-QR-code")
9 | .alias("pqr")
10 | .option("-p, --path [path]", "the path to your qr code image")
11 | .option(
12 | "-a, --accountName [accountName]",
13 | "github account name, used to publish to the pull request as a comment"
14 | )
15 | .option(
16 | "-k --key [key]",
17 | "github account key, used to publish to the pull request as a comment"
18 | )
19 | .option(
20 | "-i --issueNumber [issueNumber]",
21 | "github issue number for the pull request you wish to post to"
22 | )
23 | .option(
24 | "-r --repository [repository]",
25 | "gitbug organisation and repo e.g. newsuk/times-components"
26 | )
27 | .action(async options => {
28 | const { path, accountName, key, issueNumber, repository } = options;
29 |
30 | if (!path)
31 | log.error("publish-QR-code", "no path for generated qrcode, use -p");
32 | if (!accountName)
33 | log.error("publish-QR-code", "no github account name, use -a");
34 | if (!key) log.error("publish-QR-code", "no github account key, use -k");
35 | if (!issueNumber)
36 | log.error("publish-QR-code", "no github issue number, use -i");
37 | if (!repository)
38 | log.error(
39 | "publish-QR-code",
40 | "no git organisation and repository specified"
41 | );
42 | if (!path || !accountName || !key || !issueNumber || !repository)
43 | process.exit(1);
44 | await githubCommentManager.deleteAllExpoComments(
45 | accountName,
46 | key,
47 | issueNumber,
48 | repository
49 | );
50 | await githubCommentManager.createNewExpoComment(
51 | accountName,
52 | key,
53 | path,
54 | issueNumber,
55 | repository
56 | );
57 | });
58 | program.parse(process.argv);
59 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIDevice.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | #if XCT_UI_TESTING_AVAILABLE
9 |
10 | #if TARGET_OS_IPHONE
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /*!
17 | * @enum XCUIDeviceButton
18 | *
19 | * Represents a physical button on a device.
20 | *
21 | * @note Some buttons are not available in the Simulator, and should not be used in your tests.
22 | * You can use a block like this:
23 | *
24 | * #if !TARGET_OS_SIMULATOR
25 | * // test code that depends on buttons not available in the Simulator
26 | * #endif
27 | *
28 | * in your test code to ensure it does not call unavailable APIs.
29 | */
30 | typedef NS_ENUM(NSInteger, XCUIDeviceButton) {
31 | XCUIDeviceButtonHome = 1,
32 | XCUIDeviceButtonVolumeUp XCTEST_SIMULATOR_UNAVAILABLE("This API is not available in the Simulator, see the XCUIDeviceButton documentation for details.") = 2,
33 | XCUIDeviceButtonVolumeDown XCTEST_SIMULATOR_UNAVAILABLE("This API is not available in the Simulator, see the XCUIDeviceButton documentation for details.") = 3
34 | };
35 |
36 | /*! Represents a device, providing an interface for simulating events involving physical buttons and device state. */
37 | NS_CLASS_AVAILABLE(NA, 9_0)
38 | @interface XCUIDevice : NSObject
39 |
40 | /*! The current device. */
41 | + (XCUIDevice *)sharedDevice;
42 |
43 | #if TARGET_OS_IOS
44 | /*! The orientation of the device. */
45 | @property (nonatomic) UIDeviceOrientation orientation;
46 |
47 | /*!
48 | * Provides access to an object representing the Siri interface on the device.
49 | */
50 | @property (readonly) XCUISiriService *siriService NS_AVAILABLE_IOS(10_3);
51 | #endif
52 |
53 | /*! Simulates the user pressing a physical button. */
54 | - (void)pressButton:(XCUIDeviceButton)button;
55 |
56 | @end
57 |
58 | NS_ASSUME_NONNULL_END
59 |
60 | #endif
61 |
62 | #endif
63 |
64 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Submitting an Issue
2 |
3 | Before you submit your issue please search the issue archive
4 |
5 | If your issue appears to be a bug, providing the following information will increase the chances of your issue being dealt with quickly:
6 |
7 | - Overview of the Issue - if an error is being thrown a non-minified stack trace helps
8 | - Motivation for or Use Case - explain why this is a bug for you
9 | - Browsers and Operating System - is this a problem with all browsers or only specific ones?
10 | - Reproduce the Error - provide a live example
11 | - Related Issues - has a similar issue been reported before?
12 | - Suggest a Fix - if you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit)
13 |
14 |
15 | ## Submitting a Pull Request
16 | ### Testing
17 |
18 | Ensure every new module has sufficient testing in place, ideally aiming for 100% coverage where possible.
19 | You are able to see coverage by running
20 | `yarn test:unit - --coverage`
21 |
22 |
23 | Where appropriate (i.e. new features) there should also be a new e2e example created in `*.fructose.@(web|ios|android).js`.
24 |
25 | On submitting a PR all unit, integration and e2e tests will run. If a failure occurs your PR will not be approved.
26 |
27 | ### Commit messages
28 |
29 | When committing please follow the set convention below:
30 |
31 | ```
32 | feat: A new feature
33 | fix: A bug fix
34 | docs: Documentation only changes
35 | style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
36 | refactor: A code change that neither fixes a bug nor adds a feature
37 | perf: A code change that improves performance
38 | test: Adding missing or correcting existing tests
39 | chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
40 | ```
41 |
42 | Fructose uses an auto publishing feature that uses this commit convention to work out the bump version.
43 |
44 | [detox]: https://github.com/wix/detox/blob/master/docs/Introduction.GettingStarted.md
45 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestCaseRun.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | @class XCTestCase;
37 |
38 | @interface XCTestCaseRun : XCTestRun
39 |
40 | - (void)recordFailureInTest:(XCTestCase *)testCase withDescription:(NSString *)description inFile:(NSString *)filePath atLine:(NSUInteger)lineNumber expected:(BOOL)expected DEPRECATED_ATTRIBUTE;
41 |
42 | @end
43 |
44 | NS_ASSUME_NONNULL_END
45 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestSuiteRun.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | @interface XCTestSuiteRun : XCTestRun {
37 | #ifndef __OBJC2__
38 | @private
39 | NSMutableArray *_testRuns;
40 | #endif
41 | }
42 |
43 | @property (readonly, copy) NSArray *testRuns;
44 |
45 | - (void)addTestRun:(XCTestRun *)testRun;
46 |
47 | @end
48 |
49 | NS_ASSUME_NONNULL_END
50 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTDarwinNotificationExpectation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /*!
12 | * @typedef
13 | * Handler called when the expectation has received the Darwin notification. If the handler is not
14 | * provided the first posting of the notification will fulfill the expectation. If provided, the handler
15 | * will be queried each time the notification is received to determine whether the expectation should
16 | * be fulfilled or not. This allows the caller to check Darwin state variables or perform other logic
17 | * beyond simply verifying that the notification has been posted.
18 | */
19 | typedef BOOL (^XCTDarwinNotificationExpectationHandler)();
20 |
21 | /*!
22 | * @class XCTDarwinNotificationExpectation
23 | * Expectation subclass for waiting on a condition defined by a Darwin notification. The notification
24 | * which may be posted in the same process or by other processes.
25 | */
26 | @interface XCTDarwinNotificationExpectation : XCTestExpectation {
27 | #ifndef __OBJC2__
28 | @private
29 | id _internal;
30 | #endif
31 | }
32 |
33 | - (instancetype)init NS_UNAVAILABLE;
34 | - (instancetype)initWithDescription:(NSString *)expectationDescription NS_UNAVAILABLE;
35 |
36 | /*!
37 | * @method -initWithNotificationName:
38 | *
39 | * @discussion
40 | * Initializes an expectation that waits for a Darwin notification to be posted.
41 | */
42 | - (instancetype)initWithNotificationName:(NSString *)notificationName NS_DESIGNATED_INITIALIZER;
43 |
44 | /*!
45 | * @property notificationName
46 | * Returns the value of the notification name that was provided to the initializer.
47 | */
48 | @property (readonly, copy) NSString *notificationName;
49 |
50 | /*!
51 | * @property handler
52 | * Allows the caller to install a special handler to do custom evaluation when the notification is posted.
53 | */
54 | @property (nullable, copy) XCTDarwinNotificationExpectationHandler handler;
55 |
56 | @end
57 |
58 | NS_ASSUME_NONNULL_END
59 |
--------------------------------------------------------------------------------
/packages/web/bin/start.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const program = require("commander");
3 | const log = require("../../common/logger");
4 |
5 | program
6 | .version("0.0.1")
7 | .option(
8 | "-d, --build-dir [directory]",
9 | "specify the directory where webpack.config.js lives"
10 | )
11 | .parse(process.argv);
12 |
13 | if (!program.buildDir)
14 | throw new Error(
15 | "you must define the build directory: --build-dir [directory]"
16 | );
17 |
18 | const merge = require("webpack-merge");
19 | const webpack = require("webpack");
20 | const WebpackDevServer = require("webpack-dev-server");
21 | const path = require("path");
22 |
23 | const directory = path.resolve(program.buildDir);
24 |
25 | // eslint-disable-next-line import/no-dynamic-require
26 | const upperConfig = require(`${directory}/webpack.config.js`);
27 | const config = require("../webpack.config.js");
28 |
29 | const mergedConfig = merge(config, upperConfig);
30 | const fs = require("fs");
31 |
32 | function getHeadHtml(configDirPath) {
33 | const headHtmlPath = path.resolve(configDirPath, "head.html");
34 | let headHtml = "";
35 | if (fs.existsSync(headHtmlPath)) {
36 | headHtml = fs.readFileSync(headHtmlPath, "utf8");
37 | }
38 | return headHtml;
39 | }
40 |
41 | const headHtml = getHeadHtml(directory);
42 | const ejsTemplate = `
43 |
44 |
45 |
46 |
47 | React Native Web
48 |
49 |
50 | ${headHtml}
51 |
52 |
53 |
54 |
55 |
56 | `;
57 |
58 | fs.writeFileSync(path.join(__dirname, "../index.ejs"), ejsTemplate);
59 |
60 | new WebpackDevServer(webpack(mergedConfig), {
61 | publicPath: mergedConfig.output.publicPath,
62 | contentBase: mergedConfig.output.path,
63 | hot: false,
64 | historyApiFallback: true
65 | }).listen(
66 | 3000,
67 | "localhost",
68 | err =>
69 | err
70 | ? log.info("web-start", err)
71 | : log.info("web-start", "Listening at http://localhost:3000/")
72 | );
73 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/__snapshots__/navigationHeader.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Navigation Header Renders with back icon 1`] = `
4 |
8 |
19 |
32 |
44 | Component List
45 |
46 |
47 |
48 |
49 | `;
50 |
51 | exports[`Navigation Header Renders without back icon 1`] = `
52 |
56 |
67 |
75 |
87 | Component List
88 |
89 |
90 |
91 |
92 | `;
93 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestObservationCenter.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /*!
12 | * @class XCTestObservationCenter
13 | *
14 | * The XCTestObservationCenter distributes information about the progress of test runs to registered
15 | * observers. Observers can be any object conforming to the XCTestObservation protocol.
16 | *
17 | * If an NSPrincipalClass is declared in the test bundle's Info.plist, XCTest automatically creates a
18 | * single instance of that class when the test bundle is loaded. This instance provides a means to register
19 | * observers or do other pretesting global set up.
20 | *
21 | * Observers must be registered manually. The NSPrincipalClass instance is not automatically
22 | * registered as an observer even if the class conforms to .
23 | */
24 | @interface XCTestObservationCenter : NSObject {
25 | #ifndef __OBJC2__
26 | @private
27 | id _internalImplementation;
28 | #endif
29 | }
30 |
31 | /*!
32 | * @method +sharedTestObservationCenter
33 | *
34 | * @return The shared XCTestObservationCenter singleton instance.
35 | */
36 | + (XCTestObservationCenter *)sharedTestObservationCenter;
37 |
38 | /*!
39 | * @method -addTestObserver:
40 | *
41 | * Register an object conforming to XCTestObservation as an observer for the current test session. Observers may be added
42 | * at any time, but will not receive events that occurred before they were registered. The observation center maintains a strong
43 | * reference to observers.
44 | *
45 | * Events may be delivered to observers in any order - given observers A and B, A may be notified of a test failure before
46 | * or after B. Any ordering dependencies or serialization requirements must be managed by clients.
47 | */
48 | - (void)addTestObserver:(id )testObserver;
49 |
50 | /*!
51 | * @method -removeTestObserver:
52 | *
53 | * Unregister an object conforming to XCTestObservation as an observer for the current test session.
54 | */
55 | - (void)removeTestObserver:(id )testObserver;
56 |
57 | @end
58 |
59 | NS_ASSUME_NONNULL_END
60 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestLog.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | /*!
35 | * XCTestLog is deprecated.
36 | */
37 |
38 | DEPRECATED_ATTRIBUTE
39 | #pragma clang diagnostic push
40 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
41 | @interface XCTestLog : XCTestObserver
42 | #pragma clang diagnostic pop
43 |
44 | @property (readonly, strong) NSFileHandle *logFileHandle;
45 | - (void)testLogWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
46 | - (void)testLogWithFormat:(NSString *)format arguments:(va_list)arguments NS_FORMAT_FUNCTION(1,0);
47 |
48 | @end
49 |
50 |
--------------------------------------------------------------------------------
/ios/e2eTestsTests/e2eTestsTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | #import
14 | #import
15 |
16 | #define TIMEOUT_SECONDS 600
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface e2eTestsTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation e2eTestsTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
50 |
51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54 |
55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57 | return YES;
58 | }
59 | return NO;
60 | }];
61 | }
62 |
63 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/packages/server/index.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe it afterEach expect */
2 |
3 | const { FructoseServer } = require("./index");
4 | const client = require("socket.io-client");
5 | const portfinder = require("portfinder");
6 |
7 | describe("FructoseServer", () => {
8 | let server;
9 | let PORT;
10 | let socket;
11 | const socketConfig = {
12 | transports: ["websocket"],
13 | query: {
14 | clientType: "tests"
15 | }
16 | };
17 |
18 | const setUp = config =>
19 | portfinder
20 | .getPortPromise()
21 | .then(port => {
22 | PORT = port;
23 | server = new FructoseServer(PORT);
24 | socket = client(`http://localhost:${PORT}`, config);
25 | })
26 | .then(() => server.start());
27 |
28 | afterEach(async () => {
29 | await socket.disconnect();
30 | await server.close();
31 | });
32 |
33 | it("forwards the load-component-in-app message", done => {
34 | setUp(socketConfig).then(() => {
35 | socket.on("load-component-in-app", x => {
36 | expect(x).toBe("a component");
37 | done();
38 | });
39 | socket.emit("load-component-in-app", "a component");
40 | });
41 | });
42 |
43 | it("forwards the fructose-app-ready message", done => {
44 | setUp(socketConfig).then(() => {
45 | socket.on("fructose-app-ready", () => {
46 | done();
47 | });
48 |
49 | socket.emit("fructose-app-ready");
50 | });
51 | });
52 |
53 | it("forwards the component-loaded-in-app message", done => {
54 | setUp(socketConfig).then(() => {
55 | socket.on("component-loaded-in-app", () => {
56 | done();
57 | });
58 |
59 | socket.emit("component-loaded-in-app");
60 | });
61 | });
62 |
63 | it("forwards the get-loaded-app-components", () =>
64 | new Promise(resolve => {
65 | setUp(socketConfig).then(() => {
66 | socket.on("get-loaded-app-components", () => {
67 | resolve();
68 | });
69 |
70 | socket.emit("get-loaded-app-components");
71 | });
72 | }));
73 |
74 | it("forwards the bundled-components", () =>
75 | new Promise(resolve => {
76 | setUp(socketConfig).then(() => {
77 | socket.on("send-loaded-app-components", () => {
78 | resolve();
79 | });
80 |
81 | socket.emit("send-loaded-app-components");
82 | });
83 | }));
84 | });
85 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIApplication.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | NS_ASSUME_NONNULL_BEGIN
9 |
10 | #if XCT_UI_TESTING_AVAILABLE
11 |
12 | NS_CLASS_AVAILABLE(10_11, 9_0)
13 |
14 | /*! Proxy for an application. The information identifying the application is specified in the Xcode target settings as the "Target Application". */
15 | @interface XCUIApplication : XCUIElement
16 |
17 | /*!
18 | * Launches the application. This call is synchronous and when it returns the application is launched
19 | * and ready to handle user events. Any failure in the launch sequence is reported as a test failure
20 | * and halts the test at this point. If the application is already running, this call will first
21 | * terminate the existing instance to ensure clean state of the launched instance.
22 | */
23 | - (void)launch;
24 |
25 | /*!
26 | * Terminates any running instance of the application. If the application has an existing debug session
27 | * via Xcode, the termination is implemented as a halt via that debug connection. Otherwise, a SIGKILL
28 | * is sent to the process.
29 | */
30 | - (void)terminate;
31 |
32 | /*!
33 | * The arguments that will be passed to the application on launch. If not modified, these are the
34 | * arguments that Xcode will pass on launch. Those arguments can be changed, added to, or removed.
35 | * Unlike NSTask, it is legal to modify these arguments after the application has been launched. These
36 | * changes will not affect the current launch session, but will take effect the next time the application
37 | * is launched.
38 | */
39 | @property (nonatomic, copy) NSArray *launchArguments;
40 |
41 | /*!
42 | * The environment that will be passed to the application on launch. If not modified, this is the
43 | * environment that Xcode will pass on launch. Those variables can be changed, added to, or removed.
44 | * Unlike NSTask, it is legal to modify the environment after the application has been launched. These
45 | * changes will not affect the current launch session, but will take effect the next time the application
46 | * is launched.
47 | */
48 | @property (nonatomic, copy) NSDictionary *launchEnvironment;
49 |
50 | @end
51 |
52 | #endif
53 |
54 | NS_ASSUME_NONNULL_END
55 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestProbe.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | #import
35 |
36 | XCT_EXPORT int XCTSelfTestMain(void) DEPRECATED_ATTRIBUTE;
37 |
38 | DEPRECATED_ATTRIBUTE
39 | @interface XCTestProbe : NSObject
40 |
41 | + (BOOL)isTesting;
42 |
43 | @end
44 |
45 | XCT_EXPORT NSString * const XCTestedUnitPath DEPRECATED_ATTRIBUTE;
46 | XCT_EXPORT NSString * const XCTestScopeKey DEPRECATED_ATTRIBUTE;
47 | XCT_EXPORT NSString * const XCTestScopeAll DEPRECATED_ATTRIBUTE;
48 | XCT_EXPORT NSString * const XCTestScopeNone DEPRECATED_ATTRIBUTE;
49 | XCT_EXPORT NSString * const XCTestScopeSelf DEPRECATED_ATTRIBUTE;
50 | XCT_EXPORT NSString * const XCTestToolKey DEPRECATED_ATTRIBUTE;
51 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTNSNotificationExpectation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /*!
12 | * @class XCTNSNotificationExpectation
13 | * Expectation subclass for waiting on a condition defined by an NSNotification.
14 | */
15 | @interface XCTNSNotificationExpectation : XCTestExpectation {
16 | #ifndef __OBJC2__
17 | @private
18 | id _internal;
19 | #endif
20 | }
21 |
22 | - (instancetype)init NS_UNAVAILABLE;
23 | - (instancetype)initWithDescription:(NSString *)expectationDescription NS_UNAVAILABLE;
24 |
25 | /*!
26 | * @method -initWithName:object:notificationCenter:
27 | *
28 | * @discussion
29 | * Initializes an expectation that waits for an NSNotification to be posted by an optional object from
30 | * a given notification center.
31 | */
32 | - (instancetype)initWithName:(NSString *)notificationName object:(nullable id)object notificationCenter:(NSNotificationCenter *)notificationCenter NS_DESIGNATED_INITIALIZER;
33 |
34 | /*!
35 | * @method -initWithName:object:
36 | *
37 | * @discussion
38 | * Convenience initializer that uses the default NSNotificationCenter.
39 | */
40 | - (instancetype)initWithName:(NSString *)notificationName object:(id)object;
41 |
42 | /*!
43 | * @method -initWithName:object:
44 | *
45 | * @discussion
46 | * Convenience initializer that uses the default NSNotificationCenter and accepts the notification from any object.
47 | */
48 | - (instancetype)initWithName:(NSString *)notificationName;
49 |
50 | /*!
51 | * @property notificationName
52 | * Returns the name of the notification being waited on.
53 | */
54 | @property (readonly, copy) NSString *notificationName;
55 |
56 | /*!
57 | * @property observedObject
58 | * Returns the object that will post the notification.
59 | */
60 | @property (nullable, readonly, strong) id observedObject;
61 |
62 | /*!
63 | * @property notificationCenter
64 | * Returns the notification center that is being used.
65 | */
66 | @property (readonly, strong) NSNotificationCenter *notificationCenter;
67 |
68 | /*!
69 | * @property handler
70 | * Allows the caller to install a special handler to do custom evaluation of received notifications
71 | * matching the specified object and notification center.
72 | */
73 | @property (nullable, copy) XCNotificationExpectationHandler handler;
74 |
75 | @end
76 |
77 | NS_ASSUME_NONNULL_END
78 |
--------------------------------------------------------------------------------
/packages/client/client.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe it expect beforeAll afterEach */
2 | const Client = require("./client");
3 | const express = require("express");
4 | const http = require("http");
5 | const socketio = require("socket.io");
6 | const SocketClient = require("socket.io-client");
7 |
8 | describe("Fructose Client", () => {
9 | let app;
10 | let socketClient;
11 | let fructose;
12 | let server;
13 | let io;
14 |
15 | beforeAll(() => {
16 | app = express();
17 | server = http.Server(app);
18 | io = socketio(server);
19 | });
20 |
21 | afterEach(() => {
22 | fructose.disconnect();
23 | io.close();
24 | server.close();
25 | });
26 |
27 | it("waits for the app to load", () =>
28 | new Promise(resolve => {
29 | io.on("connection", () => {
30 | io.emit("fructose-app-ready");
31 | });
32 |
33 | server.listen(0, async () => {
34 | const { port } = server.address();
35 | socketClient = SocketClient(`http://localhost:${port}`);
36 | fructose = new Client(socketClient);
37 | await fructose.waitForApp();
38 | resolve();
39 | });
40 | }));
41 |
42 | it("can load a component", () =>
43 | new Promise(resolve => {
44 | io.on("connection", socket => {
45 | socket.on("load-component-in-app", x => {
46 | expect(x).toBe("component");
47 | io.emit("component-loaded-in-app");
48 | });
49 | });
50 |
51 | server.listen(0, () => {
52 | const { port } = server.address();
53 | socketClient = SocketClient(`http://localhost:${port}`);
54 | fructose = new Client(socketClient);
55 | expect(fructose.loadComponent("component"))
56 | .resolves.toBe("component loaded")
57 | .then(resolve);
58 | });
59 | }));
60 |
61 | it("returns a list of components loaded in the app", () =>
62 | new Promise(resolve => {
63 | const componentList = ["a", "b", "c"];
64 |
65 | io.on("connection", socket => {
66 | socket.on("get-loaded-app-components", () => {
67 | io.emit("send-loaded-app-components", componentList);
68 | });
69 | });
70 |
71 | server.listen(0, () => {
72 | const { port } = server.address();
73 | socketClient = SocketClient(`http://localhost:${port}`);
74 | fructose = new Client(socketClient);
75 | expect(fructose.getLoadedComponents())
76 | .resolves.toMatchObject(componentList)
77 | .then(resolve);
78 | });
79 | }));
80 | });
81 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestObserver.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | @class XCTestRun;
35 |
36 | /*!
37 | * XCTestObserver is deprecated.
38 | */
39 | DEPRECATED_ATTRIBUTE
40 | @interface XCTestObserver : NSObject
41 |
42 | - (void)startObserving;
43 | - (void)stopObserving;
44 | - (void)testSuiteDidStart:(XCTestRun *)testRun;
45 | - (void)testSuiteDidStop:(XCTestRun *)testRun;
46 | - (void)testCaseDidStart:(XCTestRun *)testRun;
47 | - (void)testCaseDidStop:(XCTestRun *)testRun;
48 | - (void)testCaseDidFail:(XCTestRun *)testRun withDescription:(NSString *)description inFile:(NSString *)filePath atLine:(NSUInteger)lineNumber;
49 |
50 | @end
51 |
52 | /*!
53 | * XCTestObserverClassKey is deprecated and ignored.
54 | */
55 | XCT_EXPORT NSString * const XCTestObserverClassKey DEPRECATED_ATTRIBUTE;
56 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | #if defined(__cplusplus)
35 | #define XCT_EXPORT extern "C"
36 | #else
37 | #define XCT_EXPORT extern
38 | #endif
39 |
40 | #if defined(__OBJC2__) && __OBJC2__
41 | #ifndef XCT_UI_TESTING_AVAILABLE
42 | #define XCT_UI_TESTING_AVAILABLE 1
43 | #endif
44 | #endif
45 |
46 | #ifndef XCT_UI_TESTING_AVAILABLE
47 | #define XCT_UI_TESTING_AVAILABLE 0
48 | #endif
49 |
50 | #if TARGET_OS_SIMULATOR
51 | #define XCTEST_SIMULATOR_UNAVAILABLE(_msg) __attribute__((availability(ios,unavailable,message=_msg)))
52 | #else
53 | #define XCTEST_SIMULATOR_UNAVAILABLE(_msg)
54 | #endif
55 |
56 | #if __has_attribute(warn_unused_result)
57 | #define XCT_WARN_UNUSED __attribute__((__warn_unused_result__))
58 | #else
59 | #define XCT_WARN_UNUSED
60 | #endif
61 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIElementAttributes.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | #if XCT_UI_TESTING_AVAILABLE
9 |
10 | #if TARGET_OS_IPHONE
11 |
12 | #import
13 |
14 | typedef NS_ENUM(NSInteger, XCUIUserInterfaceSizeClass) {
15 | XCUIUserInterfaceSizeClassUnspecified = UIUserInterfaceSizeClassUnspecified,
16 | XCUIUserInterfaceSizeClassCompact = UIUserInterfaceSizeClassCompact,
17 | XCUIUserInterfaceSizeClassRegular = UIUserInterfaceSizeClassRegular,
18 | };
19 |
20 | #else
21 |
22 | #import
23 |
24 | typedef NS_ENUM(NSInteger, XCUIUserInterfaceSizeClass) {
25 | XCUIUserInterfaceSizeClassUnspecified = 0,
26 | };
27 |
28 | #endif
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 | /*! Protocol describing the attributes exposed on user interface elements and available during query matching. These attributes represent data exposed to the Accessibility system. */
33 | @protocol XCUIElementAttributes
34 |
35 | /*! The accessibility identifier. */
36 | @property (readonly) NSString *identifier;
37 |
38 | /*! The frame of the element in the screen coordinate space. */
39 | @property (readonly) CGRect frame;
40 |
41 | /*! The raw value attribute of the element. Depending on the element, the actual type can vary. */
42 | @property (readonly, nullable) id value;
43 |
44 | /*! The title attribute of the element. */
45 | @property (readonly, copy) NSString *title;
46 |
47 | /*! The label attribute of the element. */
48 | @property (readonly, copy) NSString *label;
49 |
50 | /*! The type of the element. /seealso XCUIElementType. */
51 | @property (readonly) XCUIElementType elementType;
52 |
53 | /*! Whether or not the element is enabled for user interaction. */
54 | @property (readonly, getter = isEnabled) BOOL enabled;
55 |
56 | /*! The horizontal size class of the element. */
57 | @property (readonly) XCUIUserInterfaceSizeClass horizontalSizeClass;
58 |
59 | /*! The vertical size class of the element. */
60 | @property (readonly) XCUIUserInterfaceSizeClass verticalSizeClass;
61 |
62 | /*! The value that is displayed when the element has no value. */
63 | @property (readonly, nullable) NSString *placeholderValue;
64 |
65 | /*! Whether or not the element is selected. */
66 | @property (readonly, getter = isSelected) BOOL selected;
67 |
68 | #if TARGET_OS_TV
69 | /*! Whether or not the elment has UI focus. */
70 | @property (readonly) BOOL hasFocus;
71 | #endif
72 |
73 | @end
74 |
75 | NS_ASSUME_NONNULL_END
76 |
77 | #endif
78 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestExpectation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | /*!
10 | * @class XCTestExpectation
11 | *
12 | * @discussion
13 | * Expectations represent specific conditions in asynchronous testing.
14 | */
15 | @interface XCTestExpectation : NSObject {
16 | #ifndef __OBJC2__
17 | id _internalImplementation;
18 | #endif
19 | }
20 |
21 | /*!
22 | * @method -initWithDescription:
23 | * Designated initializer, requires a nonnull description of the condition the expectation is checking.
24 | */
25 | - (instancetype)initWithDescription:(NSString *)expectationDescription NS_DESIGNATED_INITIALIZER;
26 |
27 | /*!
28 | * @property expectationDescription
29 | * The human readable string used to describe the expectation in log output and test reports.
30 | */
31 | @property (copy) NSString *expectationDescription;
32 |
33 | /*!
34 | * @property inverted
35 | * If an expectation is set to have inverted behavior, then fulfilling it will have a similar effect that
36 | * failing to fulfill a conventional expectation has, as handled by the waiter and its delegate. Furthermore,
37 | * waiters that wait on an inverted expectation will allow the full timeout to elapse and not report
38 | * timeout to the delegate if it is not fulfilled.
39 | */
40 | @property (getter=isInverted) BOOL inverted;
41 |
42 | /*!
43 | * @property expectedFulfillmentCount
44 | * The expectedFulfillmentCount is the number of times -fulfill must be called on the expectation in order for it
45 | * to report complete fulfillment to its waiter. By default, expectations have a fufillmentCount of 1.
46 | * This value must be greater than 0 and is not meaningful if combined with @inverted.
47 | */
48 | @property (nonatomic) NSUInteger expectedFulfillmentCount;
49 |
50 | /*!
51 | * If set, calls to fulfill() after the expectation has already been fulfilled - exceeding the fulfillment
52 | * count - will raise. This is the legacy behavior of expectations created through APIs on XCTestCase
53 | * but is not enabled for expectations created using XCTestExpectation initializers.
54 | */
55 | @property (nonatomic) BOOL assertForOverFulfill;
56 |
57 | /*!
58 | * @method -fulfill
59 | *
60 | * @discussion
61 | * Call -fulfill to mark an expectation as having been met. It's an error to call
62 | * -fulfill on an expectation that has already been fulfilled or when the test case
63 | * that vended the expectation has already completed.
64 | */
65 | - (void)fulfill;
66 |
67 | @end
68 |
69 | NS_ASSUME_NONNULL_END
70 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/navigation.test.js:
--------------------------------------------------------------------------------
1 | /* globals describe beforeEach it expect */
2 |
3 | import React from "react";
4 | import express from "express";
5 | import http from "http";
6 | import socketio from "socket.io";
7 |
8 | import { configure, shallow } from "enzyme";
9 | import Adapter from "enzyme-adapter-react-16";
10 | import Navigation from "./navigation";
11 |
12 | configure({
13 | adapter: new Adapter()
14 | });
15 |
16 | describe("Navigation", () => {
17 | let app;
18 | let server;
19 | let io;
20 |
21 | beforeAll(() => {
22 | app = express();
23 | server = http.Server(app);
24 | io = socketio(server);
25 | });
26 |
27 | beforeEach(done => {
28 | server.listen(7811, done);
29 | });
30 |
31 | afterEach(() => server.close());
32 |
33 | it("emits when the app is ready", done => {
34 | app = shallow();
35 |
36 | io.on("connection", socket => {
37 | socket.on("fructose-app-ready", () => {
38 | done();
39 | });
40 | });
41 | });
42 |
43 | it("send a list of loaded components in the app", done => {
44 | app = shallow(
45 |
48 | );
49 |
50 | io.on("connection", socket => {
51 | socket.on("send-loaded-app-components", sentComponents => {
52 | expect(sentComponents).toEqual(["componentloaded", "anothercomponent"]);
53 | done();
54 | });
55 |
56 | socket.emit("get-loaded-app-components");
57 | });
58 | });
59 |
60 | it("loads a component in the app", done => {
61 | const navigationMock = { navigate: jest.fn() };
62 | app = shallow(
63 |
67 | );
68 |
69 | io.on("connection", socket => {
70 | socket.emit("load-component-in-app", "componentloaded");
71 |
72 | setTimeout(() => {
73 | expect(navigationMock.navigate).toBeCalledWith("componentloaded");
74 | done();
75 | }, 5);
76 | });
77 | });
78 |
79 | it("renders when is parent menu", () => {
80 | app = shallow(
81 |
84 | );
85 | expect(app).toMatchSnapshot();
86 | });
87 |
88 | it("renders when is child menu", () => {
89 | app = shallow(
90 |
93 | );
94 | app.setState({ isParentMenu: false });
95 | expect(app).toMatchSnapshot();
96 | });
97 | });
98 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIKeyboardKeys.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | #if XCT_UI_TESTING_AVAILABLE
9 |
10 | /*!
11 | Constants for use with -[XCUIElement typeKey:modifierFlags:],
12 | representing keys that have no textual representation. These comprise
13 | the set of control, function, and modifier keys found on most keyboards.
14 | */
15 |
16 | extern NSString *const XCUIKeyboardKeyDelete;
17 | extern NSString *const XCUIKeyboardKeyReturn;
18 | extern NSString *const XCUIKeyboardKeyEnter;
19 | extern NSString *const XCUIKeyboardKeyTab;
20 | extern NSString *const XCUIKeyboardKeySpace;
21 | extern NSString *const XCUIKeyboardKeyEscape;
22 |
23 | extern NSString *const XCUIKeyboardKeyUpArrow;
24 | extern NSString *const XCUIKeyboardKeyDownArrow;
25 | extern NSString *const XCUIKeyboardKeyLeftArrow;
26 | extern NSString *const XCUIKeyboardKeyRightArrow;
27 |
28 | extern NSString *const XCUIKeyboardKeyF1;
29 | extern NSString *const XCUIKeyboardKeyF2;
30 | extern NSString *const XCUIKeyboardKeyF3;
31 | extern NSString *const XCUIKeyboardKeyF4;
32 | extern NSString *const XCUIKeyboardKeyF5;
33 | extern NSString *const XCUIKeyboardKeyF6;
34 | extern NSString *const XCUIKeyboardKeyF7;
35 | extern NSString *const XCUIKeyboardKeyF8;
36 | extern NSString *const XCUIKeyboardKeyF9;
37 | extern NSString *const XCUIKeyboardKeyF10;
38 | extern NSString *const XCUIKeyboardKeyF11;
39 | extern NSString *const XCUIKeyboardKeyF12;
40 | extern NSString *const XCUIKeyboardKeyF13;
41 | extern NSString *const XCUIKeyboardKeyF14;
42 | extern NSString *const XCUIKeyboardKeyF15;
43 | extern NSString *const XCUIKeyboardKeyF16;
44 | extern NSString *const XCUIKeyboardKeyF17;
45 | extern NSString *const XCUIKeyboardKeyF18;
46 | extern NSString *const XCUIKeyboardKeyF19;
47 |
48 | extern NSString *const XCUIKeyboardKeyForwardDelete;
49 | extern NSString *const XCUIKeyboardKeyHome;
50 | extern NSString *const XCUIKeyboardKeyEnd;
51 | extern NSString *const XCUIKeyboardKeyPageUp;
52 | extern NSString *const XCUIKeyboardKeyPageDown;
53 | extern NSString *const XCUIKeyboardKeyClear;
54 | extern NSString *const XCUIKeyboardKeyHelp;
55 |
56 | extern NSString *const XCUIKeyboardKeyCapsLock;
57 | extern NSString *const XCUIKeyboardKeyShift;
58 | extern NSString *const XCUIKeyboardKeyControl;
59 | extern NSString *const XCUIKeyboardKeyOption;
60 | extern NSString *const XCUIKeyboardKeyCommand;
61 | extern NSString *const XCUIKeyboardKeyRightShift;
62 | extern NSString *const XCUIKeyboardKeyRightControl;
63 | extern NSString *const XCUIKeyboardKeyRightOption;
64 | extern NSString *const XCUIKeyboardKeyRightCommand;
65 | extern NSString *const XCUIKeyboardKeySecondaryFn;
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUICoordinate.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | #if TARGET_OS_IPHONE
8 | #import
9 | #else
10 | #import
11 | #endif
12 |
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | #if XCT_UI_TESTING_AVAILABLE && !TARGET_OS_TV
17 |
18 | @class XCUIElement;
19 |
20 | NS_CLASS_AVAILABLE(10_11, 9_0)
21 |
22 | /*! A coordinate represents a location on screen, relative to some element. Coordinates are dynamic, just like the elements to which they refer, and may compute different screen locations at different times, or be invalid if the referenced element does not exist. */
23 | @interface XCUICoordinate : NSObject
24 |
25 | /*! Coordinates are never instantiated directly. Instead, they are created by elements or by other coordinates. */
26 | - (instancetype)init NS_UNAVAILABLE;
27 |
28 | /*! The element that the coordinate is based on, either directly or via the coordinate from which it was derived. */
29 | @property (readonly) XCUIElement *referencedElement;
30 |
31 | /*! The dynamically computed value of the coordinate's location on screen. Note that this value is dependent on the current frame of the referenced element; if the element's frame changes, so will the value returned by this property. If the referenced element does exist when this is called, it will fail the test; check the referenced element's exists property if the element may not be present. */
32 | @property (readonly) CGPoint screenPoint;
33 |
34 | /*! Creates a new coordinate with an absolute offset in points from the original coordinate. */
35 | - (XCUICoordinate *)coordinateWithOffset:(CGVector)offsetVector;
36 |
37 | @end
38 |
39 | #if TARGET_OS_IPHONE
40 |
41 | @interface XCUICoordinate (XCUICoordinateTouchEvents)
42 |
43 | - (void)tap;
44 | - (void)doubleTap;
45 | - (void)pressForDuration:(NSTimeInterval)duration;
46 | - (void)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate;
47 |
48 | @end
49 |
50 | #endif // TARGET_OS_IPHONE
51 |
52 | #if TARGET_OS_OSX
53 |
54 | @interface XCUICoordinate (XCUICoordinateMouseEvents)
55 |
56 | - (void)hover;
57 | - (void)click;
58 | - (void)doubleClick;
59 | - (void)rightClick;
60 | - (void)clickForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate;
61 | - (void)scrollByDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY;
62 |
63 | @end
64 |
65 | @interface XCUICoordinate (XCUICoordinateTouchBarEvents)
66 |
67 | - (void)tap;
68 | - (void)doubleTap;
69 | - (void)pressForDuration:(NSTimeInterval)duration;
70 | - (void)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate;
71 |
72 | @end
73 |
74 | #endif // TARGET_OS_OSX
75 |
76 | #endif
77 |
78 | NS_ASSUME_NONNULL_END
79 |
--------------------------------------------------------------------------------
/packages/server/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const http = require("http");
3 | const socketio = require("socket.io");
4 | const enableDestroy = require("server-destroy");
5 | const log = require("../common/logger");
6 |
7 | const handleConnectionType = (io, clientType) => {
8 | if (clientType.includes("tests")) {
9 | log.info("server-index", "fructose client connected to Fructose Server");
10 | }
11 | };
12 | class FructoseServer {
13 | constructor(port) {
14 | this.app = null;
15 | this.server = null;
16 | this.io = null;
17 | this.i = null;
18 | this.port = port;
19 | }
20 |
21 | close() {
22 | return new Promise(resolve => {
23 | log.info("server-index", "Fructose server terminating");
24 | this.server.destroy(resolve);
25 | });
26 | }
27 |
28 | start() {
29 | return new Promise(resolve => {
30 | log.info("server-index", "Fructose Server starting");
31 | this.app = express();
32 | this.server = http.Server(this.app);
33 | this.io = socketio(this.server);
34 |
35 | this.app.get("/", (req, res) => {
36 | res.sendFile(`${__dirname}/index.html`);
37 | });
38 |
39 | this.io.on("connection", socket => {
40 | if (socket.handshake.query.clientType) {
41 | handleConnectionType(this.io, socket.handshake.query.clientType);
42 | }
43 |
44 | socket.on("fructose-app-ready", () => {
45 | this.io.emit("fructose-app-ready");
46 | });
47 |
48 | socket.on("load-component-in-app", componentName => {
49 | this.io.emit("load-component-in-app", componentName);
50 | });
51 |
52 | socket.on("component-loaded-in-app", () => {
53 | this.io.emit("component-loaded-in-app");
54 | });
55 |
56 | socket.on("send-loaded-app-components", componentKeys => {
57 | log.verbose(
58 | "server-index",
59 | "Fructose App sending bundled components"
60 | );
61 | this.io.emit("send-loaded-app-components", componentKeys);
62 | });
63 |
64 | socket.on("get-loaded-app-components", () => {
65 | this.io.emit("get-loaded-app-components");
66 | });
67 |
68 | socket.on("component-error", ({ component, error }) => {
69 | log.error("server-index", `Error found in component: ${component}`);
70 | log.error("server-index", error);
71 | });
72 |
73 | socket.on("component-not-found", component => {
74 | log.error(
75 | "server-index",
76 | `Error component not found in app: ${component}`
77 | );
78 | });
79 | });
80 |
81 | this.server.listen(this.port, () => {
82 | enableDestroy(this.server);
83 | resolve();
84 | });
85 | });
86 | }
87 | }
88 |
89 | module.exports = { FructoseServer };
90 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/IDEBundleInjection.framework/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Info.plist
8 |
9 | dPPSLt6JHJs4MODwI/naGCfVaCI=
10 |
11 | version.plist
12 |
13 | l5CwN5oWxQMrrcwfwRK++Olu3bw=
14 |
15 |
16 | files2
17 |
18 | version.plist
19 |
20 | l5CwN5oWxQMrrcwfwRK++Olu3bw=
21 |
22 |
23 | rules
24 |
25 | ^
26 |
27 | ^.*\.lproj/
28 |
29 | optional
30 |
31 | weight
32 | 1000
33 |
34 | ^.*\.lproj/locversion.plist$
35 |
36 | omit
37 |
38 | weight
39 | 1100
40 |
41 | ^version.plist$
42 |
43 |
44 | rules2
45 |
46 | .*\.dSYM($|/)
47 |
48 | weight
49 | 11
50 |
51 | ^
52 |
53 | weight
54 | 20
55 |
56 | ^(.*/)?\.DS_Store$
57 |
58 | omit
59 |
60 | weight
61 | 2000
62 |
63 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
64 |
65 | nested
66 |
67 | weight
68 | 10
69 |
70 | ^.*
71 |
72 | ^.*\.lproj/
73 |
74 | optional
75 |
76 | weight
77 | 1000
78 |
79 | ^.*\.lproj/locversion.plist$
80 |
81 | omit
82 |
83 | weight
84 | 1100
85 |
86 | ^Info\.plist$
87 |
88 | omit
89 |
90 | weight
91 | 20
92 |
93 | ^PkgInfo$
94 |
95 | omit
96 |
97 | weight
98 | 20
99 |
100 | ^[^/]+$
101 |
102 | nested
103 |
104 | weight
105 | 10
106 |
107 | ^embedded\.provisionprofile$
108 |
109 | weight
110 | 20
111 |
112 | ^version\.plist$
113 |
114 | weight
115 | 20
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/PlugIns/e2eTestsTests.xctest/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Info.plist
8 |
9 | rPai3JVXGQCACNk1J84dr/UFJQc=
10 |
11 |
12 | files2
13 |
14 | rules
15 |
16 | ^
17 |
18 | ^.*\.lproj/
19 |
20 | optional
21 |
22 | weight
23 | 1000
24 |
25 | ^.*\.lproj/locversion.plist$
26 |
27 | omit
28 |
29 | weight
30 | 1100
31 |
32 | ^Base\.lproj/
33 |
34 | weight
35 | 1010
36 |
37 | ^version.plist$
38 |
39 |
40 | rules2
41 |
42 | .*\.dSYM($|/)
43 |
44 | weight
45 | 11
46 |
47 | ^
48 |
49 | weight
50 | 20
51 |
52 | ^(.*/)?\.DS_Store$
53 |
54 | omit
55 |
56 | weight
57 | 2000
58 |
59 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
60 |
61 | nested
62 |
63 | weight
64 | 10
65 |
66 | ^.*
67 |
68 | ^.*\.lproj/
69 |
70 | optional
71 |
72 | weight
73 | 1000
74 |
75 | ^.*\.lproj/locversion.plist$
76 |
77 | omit
78 |
79 | weight
80 | 1100
81 |
82 | ^Base\.lproj/
83 |
84 | weight
85 | 1010
86 |
87 | ^Info\.plist$
88 |
89 | omit
90 |
91 | weight
92 | 20
93 |
94 | ^PkgInfo$
95 |
96 | omit
97 |
98 | weight
99 | 20
100 |
101 | ^[^/]+$
102 |
103 | nested
104 |
105 | weight
106 | 10
107 |
108 | ^embedded\.provisionprofile$
109 |
110 | weight
111 | 20
112 |
113 | ^version\.plist$
114 |
115 | weight
116 | 20
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/XCUIRecorderService.xpc/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Info.plist
8 |
9 | gXl98PRsHnj5lmC2D5fgvPS28To=
10 |
11 | version.plist
12 |
13 | mbsMPuPV++McJcw2lEghJTGkw5g=
14 |
15 |
16 | files2
17 |
18 | version.plist
19 |
20 | mbsMPuPV++McJcw2lEghJTGkw5g=
21 |
22 |
23 | rules
24 |
25 | ^
26 |
27 | ^.*\.lproj/
28 |
29 | optional
30 |
31 | weight
32 | 1000
33 |
34 | ^.*\.lproj/locversion.plist$
35 |
36 | omit
37 |
38 | weight
39 | 1100
40 |
41 | ^version.plist$
42 |
43 |
44 | rules2
45 |
46 | .*\.dSYM($|/)
47 |
48 | weight
49 | 11
50 |
51 | ^
52 |
53 | weight
54 | 20
55 |
56 | ^(.*/)?\.DS_Store$
57 |
58 | omit
59 |
60 | weight
61 | 2000
62 |
63 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
64 |
65 | nested
66 |
67 | weight
68 | 10
69 |
70 | ^.*
71 |
72 | ^.*\.lproj/
73 |
74 | optional
75 |
76 | weight
77 | 1000
78 |
79 | ^.*\.lproj/locversion.plist$
80 |
81 | omit
82 |
83 | weight
84 | 1100
85 |
86 | ^Info\.plist$
87 |
88 | omit
89 |
90 | weight
91 | 20
92 |
93 | ^PkgInfo$
94 |
95 | omit
96 |
97 | weight
98 | 20
99 |
100 | ^[^/]+$
101 |
102 | nested
103 |
104 | weight
105 | 10
106 |
107 | ^embedded\.provisionprofile$
108 |
109 | weight
110 | 20
111 |
112 | ^version\.plist$
113 |
114 | weight
115 | 20
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/XPCServices/xctestSymbolicator.xpc/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Info.plist
8 |
9 | zUybWWAy9BVyhhwqZrin9j97sy4=
10 |
11 | version.plist
12 |
13 | mbsMPuPV++McJcw2lEghJTGkw5g=
14 |
15 |
16 | files2
17 |
18 | version.plist
19 |
20 | mbsMPuPV++McJcw2lEghJTGkw5g=
21 |
22 |
23 | rules
24 |
25 | ^
26 |
27 | ^.*\.lproj/
28 |
29 | optional
30 |
31 | weight
32 | 1000
33 |
34 | ^.*\.lproj/locversion.plist$
35 |
36 | omit
37 |
38 | weight
39 | 1100
40 |
41 | ^version.plist$
42 |
43 |
44 | rules2
45 |
46 | .*\.dSYM($|/)
47 |
48 | weight
49 | 11
50 |
51 | ^
52 |
53 | weight
54 | 20
55 |
56 | ^(.*/)?\.DS_Store$
57 |
58 | omit
59 |
60 | weight
61 | 2000
62 |
63 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
64 |
65 | nested
66 |
67 | weight
68 | 10
69 |
70 | ^.*
71 |
72 | ^.*\.lproj/
73 |
74 | optional
75 |
76 | weight
77 | 1000
78 |
79 | ^.*\.lproj/locversion.plist$
80 |
81 | omit
82 |
83 | weight
84 | 1100
85 |
86 | ^Info\.plist$
87 |
88 | omit
89 |
90 | weight
91 | 20
92 |
93 | ^PkgInfo$
94 |
95 | omit
96 |
97 | weight
98 | 20
99 |
100 | ^[^/]+$
101 |
102 | nested
103 |
104 | weight
105 | 10
106 |
107 | ^embedded\.provisionprofile$
108 |
109 | weight
110 | 20
111 |
112 | ^version\.plist$
113 |
114 | weight
115 | 20
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Disabling obfuscation is useful if you collect stack traces from production crashes
20 | # (unless you are using a system that supports de-obfuscate the stack traces).
21 | -dontobfuscate
22 |
23 | # React Native
24 |
25 | # Keep our interfaces so they can be used by other ProGuard rules.
26 | # See http://sourceforge.net/p/proguard/bugs/466/
27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30 |
31 | # Do not strip any method/class that is annotated with @DoNotStrip
32 | -keep @com.facebook.proguard.annotations.DoNotStrip class *
33 | -keep @com.facebook.common.internal.DoNotStrip class *
34 | -keepclassmembers class * {
35 | @com.facebook.proguard.annotations.DoNotStrip *;
36 | @com.facebook.common.internal.DoNotStrip *;
37 | }
38 |
39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40 | void set*(***);
41 | *** get*();
42 | }
43 |
44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; }
46 | -keepclassmembers,includedescriptorclasses class * { native ; }
47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; }
48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; }
49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; }
50 |
51 | -dontwarn com.facebook.react.**
52 |
53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
55 | -dontwarn android.text.StaticLayout
56 |
57 | # okhttp
58 |
59 | -keepattributes Signature
60 | -keepattributes *Annotation*
61 | -keep class okhttp3.** { *; }
62 | -keep interface okhttp3.** { *; }
63 | -dontwarn okhttp3.**
64 |
65 | # okio
66 |
67 | -keep class sun.misc.Unsafe { *; }
68 | -dontwarn java.nio.file.*
69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
70 | -dontwarn okio.**
71 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2016 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 | #import
34 |
35 | #import
36 | #import
37 | #import
38 | #import
39 | #import
40 | #import
41 | #import
42 | #import
43 | #import
44 | #import
45 | #import
46 | #import
47 | #import
48 | #import
49 | #import
50 | #import
51 | #import
52 | #import
53 | #import
54 | #import
55 |
56 | #import
57 | #import
58 | #import
59 | #import
60 | #import
61 | #import
62 | #import
63 | #import
64 | #import
65 | #import
66 | #import
67 |
--------------------------------------------------------------------------------
/e2eTests/example/component-pages.showcase.js:
--------------------------------------------------------------------------------
1 | /* globals device test expect element by afterEach beforeEach */
2 |
3 | import React from "react";
4 | import { StyleSheet, Text, View } from "react-native";
5 |
6 | const styles = StyleSheet.create({
7 | green: {
8 | backgroundColor: "green",
9 | height: "100%",
10 | width: "100%"
11 | },
12 | aqua: {
13 | backgroundColor: "aqua",
14 | height: "100%",
15 | width: "100%"
16 | },
17 | blue: {
18 | backgroundColor: "blue",
19 | height: "100%",
20 | width: "100%"
21 | },
22 | black: {
23 | backgroundColor: "black",
24 | height: "100%",
25 | width: "100%",
26 | color: "white",
27 | fontSize: 100
28 | },
29 | orange: {
30 | backgroundColor: "orange",
31 | height: "100%",
32 | width: "100%"
33 | },
34 | purple: {
35 | backgroundColor: "purple",
36 | height: "100%",
37 | width: "100%"
38 | },
39 | yellow: {
40 | backgroundColor: "yellow",
41 | height: "100%",
42 | width: "100%",
43 | fontSize: 50,
44 | fontWeight: "bold"
45 | }
46 | });
47 |
48 | const Break = props => {
49 | this.break();
50 | return (
51 |
52 | ERROR
53 |
54 | );
55 | };
56 |
57 | export default {
58 | name: "Example Pages/Tests",
59 | children: [
60 | {
61 | type: "story",
62 | name: "The Stone",
63 | component: () => (
64 | The Philosopher's Stone
65 | )
66 | },
67 | {
68 | type: "story",
69 | name: "The Chamber",
70 | component: () => The Chamber of Secrets
71 | },
72 | {
73 | type: "story",
74 | name: "The Prisoner",
75 | component: () => The Prisoner of Azkaban
76 | },
77 | {
78 | type: "story",
79 | name: "The Goblet",
80 | component: () => The Goblet of Fire
81 | },
82 | {
83 | type: "story",
84 | name: "The Order",
85 | component: () => (
86 | The Order of the Phoenix
87 | )
88 | },
89 | {
90 | type: "story",
91 | name: "The Prince",
92 | component: () => The Half Blood Prince
93 | },
94 | {
95 | type: "story",
96 | name: "The Hallows",
97 | component: () => The Deathly Hallows
98 | },
99 | {
100 | type: "story",
101 | name: "The Internal JS Error",
102 | component: () =>
103 | },
104 | {
105 | type: "story",
106 | name: "The Handle undefined Knob showcase",
107 | component: ({ undefinedKnob }) => {undefinedKnob()}
108 | },
109 | {
110 | type: "story",
111 | name: "The Handle knob showcase",
112 | component: ({ e2eTestDontDelete }) => {e2eTestDontDelete()}
113 | }
114 | ]
115 | };
116 |
--------------------------------------------------------------------------------
/e2eTests/example/component-primitives.showcase.js:
--------------------------------------------------------------------------------
1 | /* globals device test expect element by afterEach beforeEach */
2 |
3 | import React from "react";
4 | import { StyleSheet, Text, View } from "react-native";
5 |
6 | const styles = StyleSheet.create({
7 | green: {
8 | backgroundColor: "green",
9 | height: "100%",
10 | width: "100%"
11 | },
12 | aqua: {
13 | backgroundColor: "aqua",
14 | height: "100%",
15 | width: "100%"
16 | },
17 | blue: {
18 | backgroundColor: "blue",
19 | height: "100%",
20 | width: "100%"
21 | },
22 | black: {
23 | backgroundColor: "black",
24 | height: "100%",
25 | width: "100%",
26 | color: "white",
27 | fontSize: 100
28 | },
29 | orange: {
30 | backgroundColor: "orange",
31 | height: "100%",
32 | width: "100%"
33 | },
34 | purple: {
35 | backgroundColor: "purple",
36 | height: "100%",
37 | width: "100%"
38 | },
39 | yellow: {
40 | backgroundColor: "yellow",
41 | height: "100%",
42 | width: "100%",
43 | fontSize: 50,
44 | fontWeight: "bold"
45 | }
46 | });
47 |
48 | const Break = props => {
49 | this.break();
50 | return (
51 |
52 | ERROR
53 |
54 | );
55 | };
56 |
57 | export default {
58 | name: "Example Primitives/Tests",
59 | children: [
60 | {
61 | type: "story",
62 | name: "The Stone",
63 | component: () => (
64 | The Philosopher's Stone
65 | )
66 | },
67 | {
68 | type: "story",
69 | name: "The Chamber",
70 | component: () => The Chamber of Secrets
71 | },
72 | {
73 | type: "story",
74 | name: "The Prisoner",
75 | component: () => The Prisoner of Azkaban
76 | },
77 | {
78 | type: "story",
79 | name: "The Goblet",
80 | component: () => The Goblet of Fire
81 | },
82 | {
83 | type: "story",
84 | name: "The Order",
85 | component: () => (
86 | The Order of the Phoenix
87 | )
88 | },
89 | {
90 | type: "story",
91 | name: "The Prince",
92 | component: () => The Half Blood Prince
93 | },
94 | {
95 | type: "story",
96 | name: "The Hallows",
97 | component: () => The Deathly Hallows
98 | },
99 | {
100 | type: "story",
101 | name: "The Internal JS Error",
102 | component: () =>
103 | },
104 | {
105 | type: "story",
106 | name: "The Handle undefined Knob showcase",
107 | component: ({ undefinedKnob }) => {undefinedKnob()}
108 | },
109 | {
110 | type: "story",
111 | name: "The Handle knob showcase",
112 | component: ({ e2eTestDontDelete }) => {e2eTestDontDelete()}
113 | }
114 | ]
115 | };
116 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIElementTypes.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | #if XCT_UI_TESTING_AVAILABLE
8 |
9 | NS_ENUM_AVAILABLE(10_11, 9_0)
10 | typedef NS_ENUM(NSUInteger, XCUIElementType) {
11 | XCUIElementTypeAny = 0,
12 | XCUIElementTypeOther = 1,
13 | XCUIElementTypeApplication = 2,
14 | XCUIElementTypeGroup = 3,
15 | XCUIElementTypeWindow = 4,
16 | XCUIElementTypeSheet = 5,
17 | XCUIElementTypeDrawer = 6,
18 | XCUIElementTypeAlert = 7,
19 | XCUIElementTypeDialog = 8,
20 | XCUIElementTypeButton = 9,
21 | XCUIElementTypeRadioButton = 10,
22 | XCUIElementTypeRadioGroup = 11,
23 | XCUIElementTypeCheckBox = 12,
24 | XCUIElementTypeDisclosureTriangle = 13,
25 | XCUIElementTypePopUpButton = 14,
26 | XCUIElementTypeComboBox = 15,
27 | XCUIElementTypeMenuButton = 16,
28 | XCUIElementTypeToolbarButton = 17,
29 | XCUIElementTypePopover = 18,
30 | XCUIElementTypeKeyboard = 19,
31 | XCUIElementTypeKey = 20,
32 | XCUIElementTypeNavigationBar = 21,
33 | XCUIElementTypeTabBar = 22,
34 | XCUIElementTypeTabGroup = 23,
35 | XCUIElementTypeToolbar = 24,
36 | XCUIElementTypeStatusBar = 25,
37 | XCUIElementTypeTable = 26,
38 | XCUIElementTypeTableRow = 27,
39 | XCUIElementTypeTableColumn = 28,
40 | XCUIElementTypeOutline = 29,
41 | XCUIElementTypeOutlineRow = 30,
42 | XCUIElementTypeBrowser = 31,
43 | XCUIElementTypeCollectionView = 32,
44 | XCUIElementTypeSlider = 33,
45 | XCUIElementTypePageIndicator = 34,
46 | XCUIElementTypeProgressIndicator = 35,
47 | XCUIElementTypeActivityIndicator = 36,
48 | XCUIElementTypeSegmentedControl = 37,
49 | XCUIElementTypePicker = 38,
50 | XCUIElementTypePickerWheel = 39,
51 | XCUIElementTypeSwitch = 40,
52 | XCUIElementTypeToggle = 41,
53 | XCUIElementTypeLink = 42,
54 | XCUIElementTypeImage = 43,
55 | XCUIElementTypeIcon = 44,
56 | XCUIElementTypeSearchField = 45,
57 | XCUIElementTypeScrollView = 46,
58 | XCUIElementTypeScrollBar = 47,
59 | XCUIElementTypeStaticText = 48,
60 | XCUIElementTypeTextField = 49,
61 | XCUIElementTypeSecureTextField = 50,
62 | XCUIElementTypeDatePicker = 51,
63 | XCUIElementTypeTextView = 52,
64 | XCUIElementTypeMenu = 53,
65 | XCUIElementTypeMenuItem = 54,
66 | XCUIElementTypeMenuBar = 55,
67 | XCUIElementTypeMenuBarItem = 56,
68 | XCUIElementTypeMap = 57,
69 | XCUIElementTypeWebView = 58,
70 | XCUIElementTypeIncrementArrow = 59,
71 | XCUIElementTypeDecrementArrow = 60,
72 | XCUIElementTypeTimeline = 61,
73 | XCUIElementTypeRatingIndicator = 62,
74 | XCUIElementTypeValueIndicator = 63,
75 | XCUIElementTypeSplitGroup = 64,
76 | XCUIElementTypeSplitter = 65,
77 | XCUIElementTypeRelevanceIndicator = 66,
78 | XCUIElementTypeColorWell = 67,
79 | XCUIElementTypeHelpTag = 68,
80 | XCUIElementTypeMatte = 69,
81 | XCUIElementTypeDockItem = 70,
82 | XCUIElementTypeRuler = 71,
83 | XCUIElementTypeRulerMarker = 72,
84 | XCUIElementTypeGrid = 73,
85 | XCUIElementTypeLevelIndicator = 74,
86 | XCUIElementTypeCell = 75,
87 | XCUIElementTypeLayoutArea = 76,
88 | XCUIElementTypeLayoutItem = 77,
89 | XCUIElementTypeHandle = 78,
90 | XCUIElementTypeStepper = 79,
91 | XCUIElementTypeTab = 80,
92 | XCUIElementTypeTouchBar = 81
93 | };
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/packages/app/src/componentLoader.test.js:
--------------------------------------------------------------------------------
1 | /* globals it expect */
2 |
3 | import loader from "./componentLoader";
4 |
5 | it("returns an object with keys when using .showcasefiles", () => {
6 | // mocks the showcase structure that is exported in times-components
7 | const mockShowcase = {
8 | default: {
9 | name: "Primitives/ArticleLabel",
10 | children: [
11 | {
12 | type: "story",
13 | name: "small",
14 | component: () => "lol"
15 | }
16 | ]
17 | }
18 | };
19 |
20 | const getShowcasesObject = () => [mockShowcase];
21 | const loadedShowcases = loader(getShowcasesObject);
22 | const returnedComponent = loadedShowcases["primitives/articlelabel:small"]();
23 | expect(returnedComponent).toEqual("lol");
24 | });
25 |
26 | it("filters out non story showcases", () => {
27 | // mocks the showcase structure that is exported in times-components
28 | const mockShowcase = {
29 | default: {
30 | name: "Primitives/ArticleLabel",
31 | children: [
32 | {
33 | type: "not a story",
34 | name: "small",
35 | component: () => "lol"
36 | }
37 | ]
38 | }
39 | };
40 |
41 | const getShowcasesObject = () => [mockShowcase];
42 |
43 | const loaded = loader(getShowcasesObject);
44 | expect(loaded).toEqual({});
45 | });
46 |
47 | it("filters out ignored story showcases", () => {
48 | // mocks the showcase structure that is exported in times-components
49 | const mockShowcase = {
50 | default: {
51 | name: "Primitives/ArticleLabel",
52 | children: [
53 | {
54 | type: "story",
55 | hasExternalDeps: true,
56 | name: "small",
57 | component: () => "lol"
58 | },
59 | {
60 | type: "story",
61 | name: "shown",
62 | component: () => "lol"
63 | }
64 | ]
65 | }
66 | };
67 |
68 | const getShowcasesObject = () => [mockShowcase];
69 |
70 | const loaded = loader(getShowcasesObject);
71 | expect(Object.keys(loaded)).toEqual(["primitives/articlelabel:shown"]);
72 | });
73 |
74 | it("returns showcases without a platform", () => {
75 | const mockShowcase = {
76 | default: {
77 | name: "Primitives/ArticleLabel",
78 | children: [
79 | {
80 | type: "story",
81 | name: "small",
82 | component: () => "lol"
83 | }
84 | ]
85 | }
86 | };
87 |
88 | const getShowcasesObject = () => [mockShowcase];
89 | const loadedShowcases = loader(getShowcasesObject);
90 | const returnedComponent = loadedShowcases["primitives/articlelabel:small"]();
91 | expect(returnedComponent).toEqual("lol");
92 | });
93 |
94 | it("filters out showcases that don't match specified plaform", () => {
95 | const mockShowcase = {
96 | default: {
97 | name: "Primitives/ArticleLabel",
98 | children: [
99 | {
100 | platform: "native",
101 | type: "story",
102 | name: "small",
103 | component: () => "lol"
104 | }
105 | ]
106 | }
107 | };
108 |
109 | const getShowcasesObject = () => [mockShowcase];
110 | const loaded = loader(getShowcasesObject, "web");
111 | expect(loaded).toEqual({});
112 | });
113 |
114 | it("does not explode when a showcase file has no default export", () => {
115 | let mockShowcase;
116 |
117 | const getShowcasesObject = () => [mockShowcase];
118 |
119 | const loaded = loader(getShowcasesObject, "web");
120 | expect(loaded).toEqual({});
121 | });
122 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestSuite.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | /*!
37 | * @class XCTestSuite
38 | * A concrete subclass of XCTest, XCTestSuite is a collection of test cases. Suites
39 | * are usually managed by the IDE, but XCTestSuite also provides API for dynamic test
40 | * and suite management:
41 |
42 | XCTestSuite *suite = [XCTestSuite testSuiteWithName:@"My tests"];
43 | [suite addTest:[MathTest testCaseWithSelector:@selector(testAdd)]];
44 | [suite addTest:[MathTest testCaseWithSelector:@selector(testDivideByZero)]];
45 |
46 | * Alternatively, a test suite can extract the tests to be run automatically. To do so,
47 | * pass the class of your test case class to the suite's constructor:
48 |
49 | XCTestSuite *suite = [XCTestSuite testSuiteForTestCaseClass:[MathTest class]];
50 |
51 | * This creates a suite with all the methods starting with "test" that take no arguments.
52 | * Also, a test suite of all the test cases found in the runtime can be created automatically:
53 |
54 | XCTestSuite *suite = [XCTestSuite defaultTestSuite];
55 |
56 | * This creates a suite of suites with all the XCTestCase subclasses methods that start
57 | * with "test" and take no arguments.
58 | */
59 | @interface XCTestSuite : XCTest {
60 | #ifndef __OBJC2__
61 | @private
62 | id _internalImplementation;
63 | #endif
64 | }
65 |
66 | + (instancetype)defaultTestSuite;
67 | + (instancetype)testSuiteForBundlePath:(NSString *)bundlePath;
68 | + (instancetype)testSuiteForTestCaseWithName:(NSString *)name;
69 | + (instancetype)testSuiteForTestCaseClass:(Class)testCaseClass;
70 |
71 | + (instancetype)testSuiteWithName:(NSString *)name;
72 | - (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
73 |
74 | - (void)addTest:(XCTest *)test;
75 |
76 | @property (readonly, copy) NSArray <__kindof XCTest *> *tests;
77 |
78 | @end
79 |
80 | NS_ASSUME_NONNULL_END
81 |
82 |
--------------------------------------------------------------------------------
/ios/e2eTests/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCAbstractTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2013-2015 Apple Inc. All rights reserved.
3 | //
4 | // Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
5 | //
6 | // Use of this source code is governed by the following license:
7 | //
8 | // Redistribution and use in source and binary forms, with or without modification,
9 | // are permitted provided that the following conditions are met:
10 | //
11 | // (1) Redistributions of source code must retain the above copyright notice,
12 | // this list of conditions and the following disclaimer.
13 | //
14 | // (2) Redistributions in binary form must reproduce the above copyright notice,
15 | // this list of conditions and the following disclaimer in the documentation
16 | // and/or other materials provided with the distribution.
17 | //
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | // IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
23 | // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | //
28 | // Note: this license is equivalent to the FreeBSD license.
29 | //
30 | // This notice may not be removed from this file.
31 |
32 | #import
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | @class XCTestRun;
37 |
38 | /*!
39 | * @class XCTest
40 | *
41 | * An abstract base class for testing. XCTestCase and XCTestSuite extend XCTest to provide
42 | * for creating, managing, and executing tests. Most developers will not need to subclass
43 | * XCTest directly.
44 | */
45 | @interface XCTest : NSObject {
46 | #ifndef __OBJC2__
47 | @private
48 | id _internal;
49 | #endif
50 | }
51 |
52 | /*!
53 | * @property testCaseCount
54 | * Number of test cases. Must be overridden by subclasses.
55 | */
56 | @property (readonly) NSUInteger testCaseCount;
57 |
58 | /*!
59 | * @property name
60 | * Test's name. Must be overridden by subclasses.
61 | */
62 | @property (readonly, copy, nullable) NSString *name;
63 |
64 | /*!
65 | * @property testRunClass
66 | * The XCTestRun subclass that will be instantiated when the test is run to hold
67 | * the test's results. Must be overridden by subclasses.
68 | */
69 | @property (readonly, nullable) Class testRunClass;
70 |
71 | /*!
72 | * @property testRun
73 | * The test run object that executed the test, an instance of testRunClass. If the test has not yet been run, this will be nil.
74 | */
75 | @property (readonly, nullable) XCTestRun *testRun;
76 |
77 | /*!
78 | * @method -performTest:
79 | * The method through which tests are executed. Must be overridden by subclasses.
80 | */
81 | - (void)performTest:(XCTestRun *)run;
82 |
83 | /*!
84 | * @method -runTest
85 | * Creates an instance of the testRunClass and passes it as a parameter to -performTest:.
86 | */
87 | - (void)runTest;
88 |
89 | /*!
90 | * @method -setUp
91 | * Setup method called before the invocation of each test method in the class.
92 | */
93 | - (void)setUp;
94 |
95 | /*!
96 | * @method -tearDown
97 | * Teardown method called after the invocation of each test method in the class.
98 | */
99 | - (void)tearDown;
100 |
101 | @end
102 |
103 | NS_ASSUME_NONNULL_END
104 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTKVOExpectation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2016 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | /*!
12 | * @class XCTKVOExpectation
13 | * Expectation subclass for waiting on a condition defined Key Value Observation of a key path for an object.
14 | */
15 | @interface XCTKVOExpectation : XCTestExpectation {
16 | #ifndef __OBJC2__
17 | @private
18 | id _internal;
19 | #endif
20 | }
21 |
22 | - (instancetype)init NS_UNAVAILABLE;
23 | - (instancetype)initWithDescription:(NSString *)expectationDescription NS_UNAVAILABLE;
24 |
25 | /*!
26 | * @method -initWithKeyPath:object:expectedValue:options:
27 | *
28 | * @discussion
29 | * Initializes an expectation that is fulfilled when a key value coding compliant change is made such
30 | * that the specified key path of the observed object has the expected value.
31 | */
32 | - (instancetype)initWithKeyPath:(NSString *)keyPath object:(id)object expectedValue:(nullable id)expectedValue options:(NSKeyValueObservingOptions)options NS_DESIGNATED_INITIALIZER;
33 |
34 | /*!
35 | * @method -initWithKeyPath:object:expectedValue:
36 | *
37 | * @discussion
38 | * Initializes an expectation that is fulfilled when a key value coding compliant change is made such
39 | * that the specified key path of the observed object has the expected value. The NSKeyValueObservingOptions
40 | * passed for this initializer include NSKeyValueObservingOptionInitial, so the object/key path will be
41 | * checked immediately. The options also include NSKeyValueObservingOptionNew and NSKeyValueObservingOptionOld,
42 | * so if a handler is used the change dictionary passed to it will contain NSKeyValueChangeNewKey and
43 | * NSKeyValueChangeOldKey entries.
44 | */
45 | - (instancetype)initWithKeyPath:(NSString *)keyPath object:(id)object expectedValue:(nullable id)expectedValue;
46 |
47 | /*!
48 | * @method -initWithKeyPath:object:
49 | *
50 | * @discussion
51 | * Convenience initializer that is fulfilled by any change to the specified key path of the observed object.
52 | * The NSKeyValueObservingOptions passed for this initializer do not include NSKeyValueObservingOptionInitial
53 | * since there is no value to check. If that behavior is desired in conjunction with a handler, use the
54 | * designated initializer. The options do include NSKeyValueObservingOptionNew and NSKeyValueObservingOptionOld,
55 | * so if a handler is used the change dictionary passed to it will contain NSKeyValueChangeNewKey and
56 | * NSKeyValueChangeOldKey entries.
57 | */
58 | - (instancetype)initWithKeyPath:(NSString *)keyPath object:(id)object;
59 |
60 | /*!
61 | * @property keyPath
62 | * Returns the key path that is being monitored for the KVO change.
63 | */
64 | @property (readonly, copy) NSString *keyPath;
65 |
66 | /*!
67 | * @property observedObject
68 | * Returns the object that is being monitored for the KVO change.
69 | */
70 | @property (readonly, strong) id observedObject;
71 |
72 | /*!
73 | * @property expectedValue
74 | * Returns the value that the expectation is waiting for the observed object/key path to have.
75 | */
76 | @property (nullable, readonly, strong) id expectedValue;
77 |
78 | /*!
79 | * @property options
80 | * The KVO options used when the expectation registered for observation.
81 | */
82 | @property (readonly) NSKeyValueObservingOptions options;
83 |
84 | /*!
85 | * @property handler
86 | * Allows the caller to install a special handler to do custom evaluation of the change to the value
87 | * of the object/key path. If a handler is set, expectedValue will be ignored.
88 | */
89 | @property (nullable, copy) XCKeyValueObservingExpectationHandler handler;
90 |
91 | @end
92 |
93 | NS_ASSUME_NONNULL_END
94 |
--------------------------------------------------------------------------------
/packages/app/src/components/navigation/navigation.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { StyleSheet, ScrollView, TouchableOpacity } from "react-native";
3 | import io from "socket.io-client";
4 | import { DrawerItems } from "react-navigation";
5 | import NavigationHeader from "./navigationHeader";
6 | import ParentNavigationItem from "./parentNavigationItem";
7 |
8 | const config = {
9 | transports: ["websocket"],
10 | query: {
11 | clientType: "app"
12 | }
13 | };
14 |
15 | const fructoseServerUrl = "http://localhost:7811";
16 |
17 | const styles = StyleSheet.create({
18 | isParentMenuTouch: {
19 | paddingLeft: 13,
20 | paddingTop: 15
21 | },
22 | header: {
23 | color: "white",
24 | fontSize: 40,
25 | textAlign: "center"
26 | },
27 | version: {
28 | padding: 10,
29 | color: "white",
30 | fontSize: 20,
31 | textAlign: "left"
32 | },
33 | text: {
34 | paddingTop: 10,
35 | color: "white",
36 | fontSize: 16,
37 | textAlign: "center"
38 | }
39 | });
40 |
41 | const getParentComponentNames = obj => [
42 | ...new Set(
43 | obj.map(item => item.key.split("/")[0]).filter(parent => parent !== "Home")
44 | )
45 | ];
46 |
47 | class Navigation extends Component {
48 | constructor({ items, ...restProps }) {
49 | super();
50 | this.socket = io(fructoseServerUrl, config);
51 | this.items = items;
52 | this.restProps = restProps;
53 | this.allComponentNames = this.items
54 | .map(component => component.key)
55 | .filter(component => component !== "Home");
56 | this.parentComponentNames = getParentComponentNames(this.items);
57 | this.navigateToCallback = this.navigateToCallback.bind(this);
58 |
59 | this.state = {
60 | isParentMenu: true
61 | };
62 |
63 | this.socket.on("load-component-in-app", componentToLoadInApp => {
64 | if (componentToLoadInApp) {
65 | this.restProps.navigation.navigate(componentToLoadInApp.toLowerCase());
66 | } else {
67 | this.restProps.navigation.navigate("Home");
68 | }
69 | });
70 |
71 | this.socket.on("get-loaded-app-components", () =>
72 | this.socket.emit("send-loaded-app-components", this.allComponentNames)
73 | );
74 | }
75 |
76 | componentDidMount() {
77 | this.socket.emit("fructose-app-ready");
78 | }
79 |
80 | componentDidUpdate() {
81 | this.socket.emit("component-loaded-in-app");
82 | }
83 |
84 | navigateToCallback() {
85 | this.setState({ isParentMenu: true });
86 | }
87 |
88 | renderParentItems(parentsToRender) {
89 | return parentsToRender.map(item => (
90 | {
94 | this.setState({
95 | isParentMenu: false,
96 | selectedParent: item
97 | });
98 | }}
99 | />
100 | ));
101 | }
102 |
103 | render() {
104 | if (this.state.isParentMenu) {
105 | return [
106 | this.state.isParentMenu}
108 | navigateToCallback={this.navigateToCallback}
109 | key="header"
110 | />,
111 |
112 |
113 | {this.renderParentItems(this.parentComponentNames)}
114 |
115 | ];
116 | }
117 |
118 | const childrenComponents = this.items.filter(
119 | item => item.key.split("/")[0] === this.state.selectedParent
120 | );
121 |
122 | return [
123 | this.state.isParentMenu}
126 | navigateToCallback={this.navigateToCallback}
127 | />,
128 |
129 |
134 |
135 | ];
136 | }
137 | }
138 |
139 | export default Navigation;
140 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIElementQuery.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | #if XCT_UI_TESTING_AVAILABLE
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | XCT_EXPORT NSString *XCUIIdentifierCloseWindow;
15 | XCT_EXPORT NSString *XCUIIdentifierMinimizeWindow;
16 | XCT_EXPORT NSString *XCUIIdentifierZoomWindow;
17 | XCT_EXPORT NSString *XCUIIdentifierFullScreenWindow;
18 |
19 | @class XCUIElement;
20 |
21 | /*! Object for locating elements that can be chained with other queries. */
22 | NS_CLASS_AVAILABLE(10_11, 9_0)
23 | @interface XCUIElementQuery : NSObject
24 |
25 | /*! Returns an element that will use the query for resolution. */
26 | @property (readonly) XCUIElement *element;
27 |
28 | /*! Evaluates the query at the time it is called and returns the number of matches found. */
29 | @property (readonly) NSUInteger count;
30 |
31 | /*! Returns an element that will resolve to the index into the query's result set. */
32 | - (XCUIElement *)elementAtIndex:(NSUInteger)index NS_DEPRECATED(10_11, 10_11, 9_0, 9_0, "Use elementBoundByIndex instead.");
33 |
34 | /*! Returns an element that will use the index into the query's results to determine which underlying accessibility element it is matched with. */
35 | - (XCUIElement *)elementBoundByIndex:(NSUInteger)index;
36 |
37 | /*! Returns an element that matches the predicate. The predicate will be evaluated against objects of type id. */
38 | - (XCUIElement *)elementMatchingPredicate:(NSPredicate *)predicate;
39 |
40 | /*! Returns an element that matches the type and identifier. */
41 | - (XCUIElement *)elementMatchingType:(XCUIElementType)elementType identifier:(nullable NSString *)identifier;
42 |
43 | /*! Keyed subscripting is implemented as a shortcut for matching an identifier only. For example, app.descendants["Foo"] -> XCUIElement. */
44 | - (XCUIElement *)objectForKeyedSubscript:(NSString *)key;
45 |
46 | /*! Immediately evaluates the query and returns an array of elements bound to the resulting accessibility elements. */
47 | @property (readonly, copy) NSArray *allElementsBoundByAccessibilityElement;
48 |
49 | /*! Immediately evaluates the query and returns an array of elements bound by the index of each result. */
50 | @property (readonly, copy) NSArray *allElementsBoundByIndex;
51 |
52 | /*! Returns a new query that finds the descendants of all the elements found by the receiver. */
53 | - (XCUIElementQuery *)descendantsMatchingType:(XCUIElementType)type;
54 |
55 | /*! Returns a new query that finds the direct children of all the elements found by the receiver. */
56 | - (XCUIElementQuery *)childrenMatchingType:(XCUIElementType)type;
57 |
58 | /*! Returns a new query that applies the specified attributes or predicate to the receiver. The predicate will be evaluated against objects of type id. */
59 | - (XCUIElementQuery *)matchingPredicate:(NSPredicate *)predicate;
60 | - (XCUIElementQuery *)matchingType:(XCUIElementType)elementType identifier:(nullable NSString *)identifier;
61 | - (XCUIElementQuery *)matchingIdentifier:(NSString *)identifier;
62 |
63 | /*! Returns a new query for finding elements that contain a descendant matching the specification. The predicate will be evaluated against objects of type id. */
64 | - (XCUIElementQuery *)containingPredicate:(NSPredicate *)predicate;
65 | - (XCUIElementQuery *)containingType:(XCUIElementType)elementType identifier:(nullable NSString *)identifier;
66 |
67 | /*!
68 | @discussion
69 | Provides debugging information about the query. The data in the string will vary based on the time
70 | at which it is captured, but it may include any of the following as well as additional data:
71 | • A description of each step of the query.
72 | • Information about the inputs and matched outputs of each step of the query.
73 | This data should be used for debugging only - depending on any of the data as part of a test is unsupported.
74 | */
75 | @property (readonly, copy) NSString *debugDescription;
76 |
77 | @end
78 |
79 | NS_ASSUME_NONNULL_END
80 |
81 | #endif
82 |
--------------------------------------------------------------------------------
/packages/test-helpers/src/bin/github-comment-manager.test.js:
--------------------------------------------------------------------------------
1 | /* global describe it expect */
2 | import githubCommentManager from "./github-comment-manager";
3 |
4 | const nock = require("nock");
5 |
6 | const account = "testAccountName";
7 | const token = "testKey";
8 | const repository = "testRepo";
9 | const pullRequest = 1;
10 | const documentPath = "index.html";
11 |
12 | const noCommentsResponse = [
13 | {
14 | id: 1,
15 | user: {
16 | login: "not test account name"
17 | }
18 | }
19 | ];
20 |
21 | const mixedCommentsResponse = [
22 | {
23 | id: 1,
24 | body: "If you use Expo, view our components by scanning this qr code:
",
25 | user: {
26 | login: "not test account name"
27 | }
28 | },
29 | {
30 | id: 2,
31 | body: "If you use Expo, view our components by scanning this qr code:
",
32 | user: {
33 | login: account
34 | }
35 | },
36 | {
37 | id: 3,
38 | body: "If you use Expo, view our components by scanning this qr code:
",
39 | user: {
40 | login: "a different non test account name"
41 | }
42 | }
43 | ];
44 |
45 | const multipleUserCommentsResponse = [
46 | {
47 | id: 1,
48 | body: "If you use Expo, view our components by scanning this qr code:
",
49 | user: {
50 | login: account
51 | }
52 | },
53 | {
54 | id: 2,
55 | body: "If you use Expo, view our components by scanning this qr code:
",
56 | user: {
57 | login: account
58 | }
59 | }
60 | ];
61 |
62 | const sameUserCommentsResponse = [
63 | {
64 | id: 1,
65 | body: "Please find visual snapshots of your changed components here:",
66 | user: {
67 | login: account
68 | }
69 | },
70 | {
71 | id: 2,
72 | body: "If you use Expo, view our components by scanning this qr code:
",
73 | user: {
74 | login: account
75 | }
76 | }
77 | ];
78 |
79 | describe("deleteAllExpoComments", () => {
80 | it("should delete multiple Expo comments", async () => {
81 | nock("https://api.github.com")
82 | .get(`/repos/${account}/${repository}/issues/${pullRequest}/comments`)
83 | .reply(200, multipleUserCommentsResponse);
84 |
85 | nock("https://api.github.com")
86 | .delete(`/repos/${account}/${repository}/issues/comments/1`)
87 | .reply(200);
88 | nock("https://api.github.com")
89 | .delete(`/repos/${account}/${repository}/issues/comments/2`)
90 | .reply(200);
91 |
92 | const deletedCount = await githubCommentManager.deleteAllExpoComments(
93 | account,
94 | token,
95 | pullRequest,
96 | repository
97 | );
98 |
99 | expect(deletedCount).toEqual(2);
100 | });
101 |
102 | it("should only delete expo comments", async () => {
103 | nock("https://api.github.com")
104 | .get(`/repos/${account}/${repository}/issues/${pullRequest}/comments`)
105 | .reply(200, sameUserCommentsResponse);
106 |
107 | nock("https://api.github.com")
108 | .delete(`/repos/${account}/${repository}/issues/comments/2`)
109 | .reply(200);
110 |
111 | const deletedCount = await githubCommentManager.deleteAllExpoComments(
112 | account,
113 | token,
114 | pullRequest,
115 | repository
116 | );
117 |
118 | expect(deletedCount).toEqual(1);
119 | });
120 | });
121 |
122 | describe("createNewExpoComment", () => {
123 | it("should create an expo comment", async () => {
124 | nock("https://api.github.com")
125 | .post(
126 | `/repos/${account}/${repository}/issues/${pullRequest}/comments`,
127 | `{"body": "If you use Expo, view our components by scanning this qr code:
This has been made possible through [Fructose](https://github.com/newsuk/fructose) "}`
128 | )
129 | .reply(200);
130 |
131 | const successful = await githubCommentManager
132 | .createNewExpoComment(
133 | account,
134 | token,
135 | documentPath,
136 | pullRequest,
137 | repository
138 | )
139 | .then(() => true)
140 | .catch(error => {
141 | console.log(error);
142 | return false;
143 | });
144 |
145 | expect(successful).toEqual(true);
146 | });
147 | });
148 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@times-components/fructose",
3 | "version": "3.12.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test:unit": "jest ./packages --verbose --forceExit",
7 | "test": "./scripts/tests.sh",
8 | "e2e:start": "node node_modules/react-native/local-cli/cli.js start --config='./e2eTests/rn-cli.config.js' --resetCache",
9 | "e2e:test": "yarn test:ios && yarn test:android && yarn test:web",
10 | "e2e:web": "packages/web/bin/start.js --build-dir ./e2eTests/fructose",
11 | "e2e:test:web": "./e2eTests/scripts/web-tests.sh",
12 | "e2e:test:ios": "./e2eTests/scripts/ios-tests.sh",
13 | "e2e:test:android": "./e2eTests/scripts/android-tests.sh",
14 | "e2e:test:android-ci": "SAUCE_USERNAME=${SAUCE_USERNAME} SAUCE_KEY=${SAUCE_KEY} ./e2eTests/scripts/android-saucelabs-tests.sh",
15 | "precommit-msg": "echo 'Pre-commit checks...' && exit 0",
16 | "lint-staged": "lint-staged",
17 | "lint:packages": "eslint . --fix",
18 | "lint:fructose": "eslint e2eTests/fructose /--fix",
19 | "lint:e2eTests": "eslint e2eTests /--fix",
20 | "prettier:diff": "prettier --list-different '**/*.js'",
21 | "prettier:write": "prettier --write '**/*.js'",
22 | "prepare": "babel packages/test-helpers/src --out-dir packages/test-helpers/lib"
23 | },
24 | "bin": {
25 | "fructose-web": "packages/web/bin/start.js",
26 | "fructose-tunnel": "packages/test-helpers/bin/createTunnel.js",
27 | "fructose": "packages/test-helpers/lib/bin/run.js"
28 | },
29 | "pre-commit": [
30 | "precommit-msg",
31 | "lint-staged"
32 | ],
33 | "lint-staged": {
34 | "**/*.js": [
35 | "lint:packages",
36 | "lint:fructose",
37 | "lint:e2eTests",
38 | "prettier --write",
39 | "git add"
40 | ]
41 | },
42 | "jest": {
43 | "preset": "react-native",
44 | "snapshotSerializers": [
45 | "enzyme-to-json/serializer"
46 | ],
47 | "modulePathIgnorePatterns": [
48 | "/packages/test-helpers/lib"
49 | ],
50 | "transformIgnorePatterns": [
51 | "node_modules/(?!react-native|react-navigation|fructose-app|@times-components/image)"
52 | ]
53 | },
54 | "dependencies": {
55 | "babel-polyfill": "^6.26.0",
56 | "callsite": "^1.0.0",
57 | "chromeless": "^1.3.0",
58 | "commander": "2.19.0",
59 | "express": "^4.16.2",
60 | "github-comment-manager": "^1.1.5",
61 | "html-webpack-plugin": "3.2.0",
62 | "ngrok": "^2.2.24",
63 | "npmlog": "^4.1.2",
64 | "prop-types": "^15.6.0",
65 | "react-native": "0.55.4",
66 | "react-native-side-menu": "^1.1.3",
67 | "react-navigation": "^2.17.0",
68 | "request": "^2.82.0",
69 | "server-destroy": "^1.0.1",
70 | "socket.io": "1.7.4",
71 | "socket.io-client": "1.7.4",
72 | "webpack": "4.6.0",
73 | "webpack-dev-server": "3.1.7",
74 | "webpack-merge": "^4.1.1"
75 | },
76 | "peerDependencies": {
77 | "react": ">= 16.3.1",
78 | "react-native": "0.55.4"
79 | },
80 | "devDependencies": {
81 | "babel-cli": "^6.26.0",
82 | "babel-core": "6.26.3",
83 | "babel-jest": "19.0.0",
84 | "babel-loader": "7.1.4",
85 | "babel-plugin-react-native-web": "^0.8.9",
86 | "babel-plugin-transform-regenerator": "^6.26.0",
87 | "babel-preset-react-native": "^4.0.0",
88 | "babel-register": "^6.26.0",
89 | "compression-webpack-plugin": "^1.0.0",
90 | "enzyme": "^3.2.0",
91 | "enzyme-adapter-react-16": "^1.1.0",
92 | "enzyme-to-json": "^3.2.2",
93 | "eslint": "4.18.0",
94 | "eslint-config-airbnb": "^16.1.0",
95 | "eslint-config-prettier": "^2.9.0",
96 | "eslint-plugin-import": "^2.8.0",
97 | "eslint-plugin-jsx-a11y": "^6.0.3",
98 | "eslint-plugin-react": "^7.6.1",
99 | "file-loader": "1.1.11",
100 | "http-serve": "^1.0.1",
101 | "jest": "23.3.0",
102 | "jest-environment-node-debug": "2.0.0",
103 | "lint-staged": "4.0.0",
104 | "nock": "^9.2.5",
105 | "portfinder": "^1.0.13",
106 | "pre-commit": "^1.2.2",
107 | "prettier": "^1.8.2",
108 | "react": "16.3.1",
109 | "react-art": "16.4.2",
110 | "react-dom": "16.4.2",
111 | "react-hot-loader": "^1.3.1",
112 | "react-native-showcase-loader": "1.0.1",
113 | "react-native-web": "0.8.9",
114 | "react-test-renderer": "16.3.1",
115 | "url-loader": "^0.5.8",
116 | "wd": "^1.4.1",
117 | "webpack-cli": "^3.1.0"
118 | },
119 | "author": "News UK & Ireland Ltd",
120 | "license": "BSD-3-Clause",
121 | "bugs": {
122 | "url": "https://github.com/rjanjua/fructose/issues"
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCTestObservation.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2014-2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | @class XCTestSuite, XCTestCase;
10 |
11 | /*!
12 | * @protocol XCTestObservation
13 | *
14 | * Objects conforming to XCTestObservation can register to be notified of the progress of test runs. See XCTestObservationCenter
15 | * for details on registration.
16 | *
17 | * Progress events are delivered in the following sequence:
18 | *
19 | * -testBundleWillStart: // exactly once per test bundle
20 | * -testSuiteWillStart: // exactly once per test suite
21 | * -testCaseWillStart: // exactly once per test case
22 | * -testCase:didFailWithDescription:... // zero or more times per test case, any time between test case start and finish
23 | * -testCaseDidFinish: // exactly once per test case
24 | * -testSuite:didFailWithDescription:... // zero or more times per test suite, any time between test suite start and finish
25 | * -testSuiteDidFinish: // exactly once per test suite
26 | * -testBundleDidFinish: // exactly once per test bundle
27 | */
28 | @protocol XCTestObservation
29 | @optional
30 |
31 | /*!
32 | * @method -testBundleWillStart:
33 | *
34 | * Sent immediately before tests begin as a hook for any pre-testing setup.
35 | *
36 | * @param testBundle The bundle containing the tests that were executed.
37 | */
38 | - (void)testBundleWillStart:(NSBundle *)testBundle;
39 |
40 | /*!
41 | * @method -testBundleDidFinish:
42 | *
43 | * Sent immediately after all tests have finished as a hook for any post-testing activity. The test process will generally
44 | * exit after this method returns, so if there is long running and/or asynchronous work to be done after testing, be sure
45 | * to implement this method in a way that it blocks until all such activity is complete.
46 | *
47 | * @param testBundle The bundle containing the tests that were executed.
48 | */
49 | - (void)testBundleDidFinish:(NSBundle *)testBundle;
50 |
51 | /*!
52 | * @method -testSuiteWillStart:
53 | *
54 | * Sent when a test suite starts executing.
55 | *
56 | * @param testSuite The test suite that started. Additional information can be retrieved from the associated XCTestRun.
57 | */
58 | - (void)testSuiteWillStart:(XCTestSuite *)testSuite;
59 |
60 | /*!
61 | * @method -testSuiteDidFail:withDescription:inFile:atLine:
62 | *
63 | * Sent when a test suite reports a failure. Suite failures are most commonly reported during suite-level setup and teardown
64 | * whereas failures during tests are reported for the test case alone and are not reported as suite failures.
65 | *
66 | * @param testSuite The test suite that failed. Additional information can be retrieved from the associated XCTestRun.
67 | * @param description A textual description of the failure.
68 | * @param filePath The path of file where the failure occurred, nil if unknown.
69 | * @param lineNumber The line where the failure was reported.
70 | */
71 | - (void)testSuite:(XCTestSuite *)testSuite didFailWithDescription:(NSString *)description inFile:(nullable NSString *)filePath atLine:(NSUInteger)lineNumber;
72 |
73 | /*!
74 | * @method -testSuiteDidFinish:
75 | *
76 | * Sent when a test suite finishes executing.
77 | *
78 | * @param testSuite The test suite that finished. Additional information can be retrieved from the associated XCTestRun.
79 | */
80 | - (void)testSuiteDidFinish:(XCTestSuite *)testSuite;
81 |
82 | /*!
83 | * @method -testCaseWillStart:
84 | *
85 | * Sent when a test case starts executing.
86 | *
87 | * @param testCase The test case that started. Additional information can be retrieved from the associated XCTestRun.
88 | */
89 | - (void)testCaseWillStart:(XCTestCase *)testCase;
90 |
91 | /*!
92 | * @method -testCaseDidFail:withDescription:inFile:atLine:
93 | *
94 | * Sent when a test case reports a failure.
95 | *
96 | * @param testCase The test case that failed. Additional information can be retrieved from the associated XCTestRun.
97 | * @param description A textual description of the failure.
98 | * @param filePath The path of file where the failure occurred, nil if unknown.
99 | * @param lineNumber The line where the failure was reported.
100 | */
101 | - (void)testCase:(XCTestCase *)testCase didFailWithDescription:(NSString *)description inFile:(nullable NSString *)filePath atLine:(NSUInteger)lineNumber;
102 |
103 | /*!
104 | * @method -testCaseDidFinish:
105 | *
106 | * Sent when a test case finishes executing.
107 | *
108 | * @param testCase The test case that finished. Additional information can be retrieved from the associated XCTestRun.
109 | */
110 | - (void)testCaseDidFinish:(XCTestCase *)testCase;
111 |
112 | @end
113 |
114 | NS_ASSUME_NONNULL_END
115 |
--------------------------------------------------------------------------------
/ios/e2eTests.app/Frameworks/XCTest.framework/Headers/XCUIElementTypeQueryProvider.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Apple Inc. All rights reserved.
3 | //
4 |
5 | #import
6 |
7 | #if XCT_UI_TESTING_AVAILABLE
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | @class XCUIElementQuery;
12 |
13 | @protocol XCUIElementTypeQueryProvider
14 |
15 | @property (readonly, copy) XCUIElementQuery *touchBars;
16 | @property (readonly, copy) XCUIElementQuery *groups;
17 | @property (readonly, copy) XCUIElementQuery *windows;
18 | @property (readonly, copy) XCUIElementQuery *sheets;
19 | @property (readonly, copy) XCUIElementQuery *drawers;
20 | @property (readonly, copy) XCUIElementQuery *alerts;
21 | @property (readonly, copy) XCUIElementQuery *dialogs;
22 | @property (readonly, copy) XCUIElementQuery *buttons;
23 | @property (readonly, copy) XCUIElementQuery *radioButtons;
24 | @property (readonly, copy) XCUIElementQuery *radioGroups;
25 | @property (readonly, copy) XCUIElementQuery *checkBoxes;
26 | @property (readonly, copy) XCUIElementQuery *disclosureTriangles;
27 | @property (readonly, copy) XCUIElementQuery *popUpButtons;
28 | @property (readonly, copy) XCUIElementQuery *comboBoxes;
29 | @property (readonly, copy) XCUIElementQuery *menuButtons;
30 | @property (readonly, copy) XCUIElementQuery *toolbarButtons;
31 | @property (readonly, copy) XCUIElementQuery *popovers;
32 | @property (readonly, copy) XCUIElementQuery *keyboards;
33 | @property (readonly, copy) XCUIElementQuery *keys;
34 | @property (readonly, copy) XCUIElementQuery *navigationBars;
35 | @property (readonly, copy) XCUIElementQuery *tabBars;
36 | @property (readonly, copy) XCUIElementQuery *tabGroups;
37 | @property (readonly, copy) XCUIElementQuery *toolbars;
38 | @property (readonly, copy) XCUIElementQuery *statusBars;
39 | @property (readonly, copy) XCUIElementQuery *tables;
40 | @property (readonly, copy) XCUIElementQuery *tableRows;
41 | @property (readonly, copy) XCUIElementQuery *tableColumns;
42 | @property (readonly, copy) XCUIElementQuery *outlines;
43 | @property (readonly, copy) XCUIElementQuery *outlineRows;
44 | @property (readonly, copy) XCUIElementQuery *browsers;
45 | @property (readonly, copy) XCUIElementQuery *collectionViews;
46 | @property (readonly, copy) XCUIElementQuery *sliders;
47 | @property (readonly, copy) XCUIElementQuery *pageIndicators;
48 | @property (readonly, copy) XCUIElementQuery *progressIndicators;
49 | @property (readonly, copy) XCUIElementQuery *activityIndicators;
50 | @property (readonly, copy) XCUIElementQuery *segmentedControls;
51 | @property (readonly, copy) XCUIElementQuery *pickers;
52 | @property (readonly, copy) XCUIElementQuery *pickerWheels;
53 | @property (readonly, copy) XCUIElementQuery *switches;
54 | @property (readonly, copy) XCUIElementQuery *toggles;
55 | @property (readonly, copy) XCUIElementQuery *links;
56 | @property (readonly, copy) XCUIElementQuery *images;
57 | @property (readonly, copy) XCUIElementQuery *icons;
58 | @property (readonly, copy) XCUIElementQuery *searchFields;
59 | @property (readonly, copy) XCUIElementQuery *scrollViews;
60 | @property (readonly, copy) XCUIElementQuery *scrollBars;
61 | @property (readonly, copy) XCUIElementQuery *staticTexts;
62 | @property (readonly, copy) XCUIElementQuery *textFields;
63 | @property (readonly, copy) XCUIElementQuery *secureTextFields;
64 | @property (readonly, copy) XCUIElementQuery *datePickers;
65 | @property (readonly, copy) XCUIElementQuery *textViews;
66 | @property (readonly, copy) XCUIElementQuery *menus;
67 | @property (readonly, copy) XCUIElementQuery *menuItems;
68 | @property (readonly, copy) XCUIElementQuery *menuBars;
69 | @property (readonly, copy) XCUIElementQuery *menuBarItems;
70 | @property (readonly, copy) XCUIElementQuery *maps;
71 | @property (readonly, copy) XCUIElementQuery *webViews;
72 | @property (readonly, copy) XCUIElementQuery *steppers;
73 | @property (readonly, copy) XCUIElementQuery *incrementArrows;
74 | @property (readonly, copy) XCUIElementQuery *decrementArrows;
75 | @property (readonly, copy) XCUIElementQuery *tabs;
76 | @property (readonly, copy) XCUIElementQuery *timelines;
77 | @property (readonly, copy) XCUIElementQuery *ratingIndicators;
78 | @property (readonly, copy) XCUIElementQuery *valueIndicators;
79 | @property (readonly, copy) XCUIElementQuery *splitGroups;
80 | @property (readonly, copy) XCUIElementQuery *splitters;
81 | @property (readonly, copy) XCUIElementQuery *relevanceIndicators;
82 | @property (readonly, copy) XCUIElementQuery *colorWells;
83 | @property (readonly, copy) XCUIElementQuery *helpTags;
84 | @property (readonly, copy) XCUIElementQuery *mattes;
85 | @property (readonly, copy) XCUIElementQuery *dockItems;
86 | @property (readonly, copy) XCUIElementQuery *rulers;
87 | @property (readonly, copy) XCUIElementQuery *rulerMarkers;
88 | @property (readonly, copy) XCUIElementQuery *grids;
89 | @property (readonly, copy) XCUIElementQuery *levelIndicators;
90 | @property (readonly, copy) XCUIElementQuery *cells;
91 | @property (readonly, copy) XCUIElementQuery *layoutAreas;
92 | @property (readonly, copy) XCUIElementQuery *layoutItems;
93 | @property (readonly, copy) XCUIElementQuery *handles;
94 | @property (readonly, copy) XCUIElementQuery *otherElements;
95 |
96 | @end
97 |
98 | NS_ASSUME_NONNULL_END
99 |
100 | #endif
101 |
--------------------------------------------------------------------------------
/ios/e2eTests.xcodeproj/xcshareddata/xcschemes/e2eTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------