Skip to content

Commit

Permalink
Made SandCastle run the same Instrumentation Tests that are open sour…
Browse files Browse the repository at this point in the history
…ced and are running on CI

Reviewed By: mkonicek

Differential Revision: D3229774

fb-gh-sync-id: 48239e8898eb011ad767bf102aa65025351363c6
fbshipit-source-id: 48239e8898eb011ad767bf102aa65025351363c6
  • Loading branch information
bestander authored and Facebook Github Bot 6 committed Apr 29, 2016
1 parent 58876d5 commit f99786c
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 12 deletions.
13 changes: 6 additions & 7 deletions ReactAndroid/src/androidTest/buck-runner/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include_defs('//ReactAndroid/DEFS')
# We are running instrumentation tests in simple mode: app code and instrumentation are in the same APK
# Currently you need to run these commands to execute tests:
#
# node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# gradle :ReactAndroid:packageReactNdkLibsForBuck
# buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
# ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests
Expand All @@ -12,13 +12,12 @@ android_binary(
manifest = 'AndroidManifest.xml',
keystore = '//keystores:debug',
deps = [
react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
react_native_integration_tests_target('assets:assets'),
react_native_dep('third-party/java/testing-support-lib:exposed-instrumentation-api'),
react_native_target('jni/prebuilt:reactnative-libs'),
react_native_target('jni/prebuilt:android-jsc'),
react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'),
react_native_dep('third-party/java/testing-support-lib:exposed-instrumentation-api'),
react_native_integration_tests_target('assets:assets'),
react_native_integration_tests_target('java/com/facebook/react/tests:tests'),
react_native_target('java/com/facebook/react/devsupport:devsupport'),
react_native_target('jni/prebuilt:android-jsc'),
react_native_target('jni/prebuilt:reactnative-libs'),
],
)

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ android_library(
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/views/picker:picker'),
],
visibility = [
'PUBLIC',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

package com.facebook.react;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Color;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.views.picker.ReactDialogPickerManager;
import com.facebook.react.views.picker.ReactDropdownPickerManager;
import com.facebook.react.views.picker.ReactPicker;
import com.facebook.react.views.picker.ReactPickerManager;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;

/**
* Integration test for {@link ReactDialogPickerManager} and {@link ReactDropdownPickerManager}
* (and, implicitly, {@link ReactPickerManager}). Tests basic properties, events and switching
* between spinner modes (which changes the used manager).
*/
public class ReactPickerTestCase extends ReactAppInstrumentationTestCase {

private static interface PickerAndroidTestModule extends JavaScriptModule {
public void selectItem(int position);
public void setMode(String mode);
public void setPrimaryColor(String color);
}

public static class PickerAndroidRecordingModule extends BaseJavaModule {
private final List<Integer> mSelections = new ArrayList<Integer>();

@Override
public String getName() {
return "PickerAndroidRecordingModule";
}

@ReactMethod
public void recordSelection(int position) {
mSelections.add(position);
}

public List<Integer> getSelections() {
return new ArrayList<Integer>(mSelections);
}
}

private PickerAndroidRecordingModule mRecordingModule;

@Override
protected String getReactApplicationKeyUnderTest() {
return "PickerAndroidTestApp";
}

@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
mRecordingModule = new PickerAndroidRecordingModule();
return super.createReactInstanceSpecForTest()
.addJSModule(PickerAndroidTestModule.class)
.addNativeModule(mRecordingModule);
}

public void testBasicProperties() {
ReactPicker spinner = getViewAtPath(0, 0);
SpinnerAdapter adapter = spinner.getAdapter();

assertEquals(Spinner.MODE_DIALOG, spinner.getMode());
assertEquals("prompt", spinner.getPrompt());
assertNotNull(adapter);
assertEquals(3, adapter.getCount());
assertEquals("item1", ((TextView) adapter.getView(0, null, null)).getText());
assertEquals("item2", ((TextView) adapter.getView(1, null, null)).getText());
assertEquals("item3", ((TextView) adapter.getView(2, null, null)).getText());
assertEquals(1, spinner.getSelectedItemPosition());

// test colors
assertEquals(Color.RED, ((TextView) adapter.getView(0, null, null)).getCurrentTextColor());
assertEquals(Color.GREEN, ((TextView) adapter.getView(1, null, null)).getCurrentTextColor());
assertEquals(Color.BLUE, ((TextView) adapter.getView(2, null, null)).getCurrentTextColor());
assertEquals(
Color.RED,
((TextView) adapter.getDropDownView(0, null, null)).getCurrentTextColor());
assertEquals(
Color.GREEN,
((TextView) adapter.getDropDownView(1, null, null)).getCurrentTextColor());
assertEquals(
Color.BLUE,
((TextView) adapter.getDropDownView(2, null, null)).getCurrentTextColor());
getTestModule().setPrimaryColor("black");
waitForBridgeAndUIIdle();
assertEquals(Color.BLACK, ((TextView) adapter.getView(0, null, null)).getCurrentTextColor());
assertEquals(Color.BLACK, ((TextView) adapter.getView(1, null, null)).getCurrentTextColor());
assertEquals(Color.BLACK, ((TextView) adapter.getView(2, null, null)).getCurrentTextColor());
assertEquals(
Color.RED,
((TextView) adapter.getDropDownView(0, null, null)).getCurrentTextColor());
assertEquals(
Color.GREEN,
((TextView) adapter.getDropDownView(1, null, null)).getCurrentTextColor());
assertEquals(
Color.BLUE,
((TextView) adapter.getDropDownView(2, null, null)).getCurrentTextColor());

}

public void testDropdownPicker() {
ReactPicker spinner = getViewAtPath(0, 1);

assertEquals(Spinner.MODE_DROPDOWN, spinner.getMode());
}

public void testDisabledPicker() {
ReactPicker spinner = getViewAtPath(0, 2);

assertFalse(spinner.isEnabled());
}

public void testUpdateSelectedItem() {
ReactPicker spinner = getViewAtPath(0, 0);
assertEquals(1, spinner.getSelectedItemPosition());

getTestModule().selectItem(2);
waitForBridgeAndUIIdle();
getInstrumentation().waitForIdleSync();

assertEquals(2, spinner.getSelectedItemPosition());
}

public void testUpdateMode() {
ReactPicker spinner = getViewAtPath(0, 1);
assertEquals(Spinner.MODE_DROPDOWN, spinner.getMode());

getTestModule().setMode("dialog");
waitForBridgeAndUIIdle();
getInstrumentation().waitForIdleSync();

// changing the spinner mode in JS actually creates a new component on the native side, as
// there's no way to change the mode once you have constructed a Spinner.
ReactPicker newPicker = getViewAtPath(0, 1);
assertTrue(spinner != newPicker);
assertEquals(Spinner.MODE_DIALOG, newPicker.getMode());
}

public void testOnSelect() throws Throwable {
runTestOnUiThread(
new Runnable() {
@Override
public void run() {
ReactPicker spinner = getViewAtPath(0, 0);
spinner.setSelection(2);
}
});

getInstrumentation().waitForIdleSync();
waitForBridgeAndUIIdle();

List<Integer> selections = mRecordingModule.getSelections();
assertEquals(1, selections.size());
assertEquals(2, (int) selections.get(0));
}

private PickerAndroidTestModule getTestModule() {
return getReactContext().getCatalystInstance().getJSModule(PickerAndroidTestModule.class);
}

}
82 changes: 82 additions & 0 deletions ReactAndroid/src/androidTest/js/PickerAndroidTestModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule PickerAndroidTestModule
*/

'use strict';

var BatchedBridge = require('BatchedBridge');
var React = require('React');
var RecordingModule = require('NativeModules').PickerAndroidRecordingModule;
var Picker = require('Picker');
var View = require('View');

var Item = Picker.Item;

var appInstance;
var PickerAndroidTestApp = React.createClass({
componentWillMount: function() {
appInstance = this;
},
getInitialState: function() {
return {
selected: 1,
mode: 'dropdown',
style: {},
};
},
render: function() {
return (
<View collapsable={false}>
<Picker
mode="dialog"
prompt="prompt"
style={this.state.style}
selectedValue={this.state.selected}
onValueChange={this.onValueChange}>
<Item label="item1" color="#ff0000" value={0} />
<Item label="item2" color="#00ff00" value={1} />
<Item label="item3" color="#0000ff" value={2} />
</Picker>
<Picker mode={this.state.mode}>
<Item label="item1" />
<Item label="item2" />
</Picker>
<Picker enabled={false}>
<Item label="item1" />
<Item label="item2" />
</Picker>
</View>
);
},
onValueChange: function(value) {
this.setState({selected: value});
RecordingModule.recordSelection(value);
},
});

var PickerAndroidTestModule = {
PickerAndroidTestApp: PickerAndroidTestApp,
selectItem: function(value) {
appInstance.setState({selected: value});
},
setMode: function(mode) {
appInstance.setState({mode: mode});
},
setPrimaryColor: function(color) {
appInstance.setState({style: {color}});
},
};

BatchedBridge.registerCallableModule(
'PickerAndroidTestModule',
PickerAndroidTestModule
);

module.exports = PickerAndroidTestModule;
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ScrollViewTestModule
*/

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
'use strict';

Expand All @@ -12,19 +14,25 @@ console.disableYellowBox = true;

// Include modules used by integration tests
require('ScrollViewTestModule');
require('PickerAndroidTestModule');

// Define catalyst test apps used in integration tests
var AppRegistry = require('AppRegistry');

var apps = [
{
appKey: 'ScrollViewTestApp',
component: () => require('ScrollViewTestModule').ScrollViewTestApp
appKey: 'ScrollViewTestApp',
component: () => require('ScrollViewTestModule').ScrollViewTestApp,
},
{
appKey: 'HorizontalScrollViewTestApp',
component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp
component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp,
},
{
appKey: 'PickerAndroidTestApp',
component: () => require('PickerAndroidTestModule').PickerAndroidTestApp,
},
];

module.exports = apps;
AppRegistry.registerConfig(apps);
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test:
- ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1:
timeout: 360
# build JS bundle for instrumentation tests
- node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/assets/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
- node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# build test APK
- buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
# run installed apk with tests
Expand Down

0 comments on commit f99786c

Please sign in to comment.