diff --git a/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap b/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap
index b7e2c081..938453b9 100644
--- a/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap
+++ b/packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap
@@ -1,6 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
+exports[`Additional CSS for styled app 1`] = `
+"
+.rn-backgroundColor-1e4kli0{background-color:purple}
+.rn-borderTopWidth-10pzpfo{border-top-width:1234px}
+.rn-borderRightWidth-1y24uml{border-right-width:1234px}
+.rn-borderBottomWidth-98wxn4{border-bottom-width:1234px}
+.rn-borderLeftWidth-150mub4{border-left-width:1234px}"
+`;
+
+exports[`AppRegistry/renderApplication getApplication returns "element" and "getStyleElement" 1`] = `
@@ -8,7 +17,7 @@ exports[`apis/AppRegistry/renderApplication getApplication 1`] = `
`;
-exports[`apis/AppRegistry/renderApplication getApplication 2`] = `
+exports[`AppRegistry/renderApplication getApplication returns "element" and "getStyleElement" 2`] = `
""
`;
+
+exports[`CSS for an unstyled app 1`] = `
+"@media all{
+html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}
+body{margin:0;}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
+input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}
+}
+@keyframes rn-ActivityIndicator-animation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}}
+@keyframes rn-ProgressBar-animation{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}100%{-webkit-transform:translateX(400%);transform:translateX(400%);}}
+.rn-alignItems-1oszu61{-ms-flex-align:stretch;-webkit-align-items:stretch;-webkit-box-align:stretch;align-items:stretch}
+.rn-borderTopStyle-1efd50x{border-top-style:solid}
+.rn-borderRightStyle-14skgim{border-right-style:solid}
+.rn-borderBottomStyle-rull8r{border-bottom-style:solid}
+.rn-borderLeftStyle-mm0ijv{border-left-style:solid}
+.rn-borderTopWidth-13yce4e{border-top-width:0px}
+.rn-borderRightWidth-fnigne{border-right-width:0px}
+.rn-borderBottomWidth-ndvcnb{border-bottom-width:0px}
+.rn-borderLeftWidth-gxnn5r{border-left-width:0px}
+.rn-boxSizing-deolkf{box-sizing:border-box}
+.rn-display-6koalj{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}
+.rn-flexShrink-1pxmb3b{-ms-flex-negative:0 !important;-webkit-flex-shrink:0 !important;flex-shrink:0 !important}
+.rn-flexBasis-7vfszb{-ms-flex-preferred-size:auto !important;-webkit-flex-basis:auto !important;flex-basis:auto !important}
+.rn-flexDirection-eqz5dr{-ms-flex-direction:column;-webkit-box-direction:normal;-webkit-box-orient:vertical;-webkit-flex-direction:column;flex-direction:column}
+.rn-marginTop-1mnahxq{margin-top:0px}
+.rn-marginRight-61z16t{margin-right:0px}
+.rn-marginBottom-p1pxzi{margin-bottom:0px}
+.rn-marginLeft-11wrixw{margin-left:0px}
+.rn-minHeight-ifefl9{min-height:0px}
+.rn-minWidth-bcqeeo{min-width:0px}
+.rn-paddingTop-wk8lta{padding-top:0px}
+.rn-paddingRight-9aemit{padding-right:0px}
+.rn-paddingBottom-1mdbw0j{padding-bottom:0px}
+.rn-paddingLeft-gy4na3{padding-left:0px}
+.rn-position-bnwqim{position:relative}
+.rn-zIndex-1lgpqti{z-index:0}
+.rn-flex-13awgt0{-ms-flex:1;-webkit-flex:1;flex:1}
+.rn-flexGrow-1m1wadx{-ms-flex-positive:1 !important;-webkit-flex-grow:1 !important;flex-grow:1 !important}
+.rn-flexShrink-1awmn5t{-ms-flex-negative:1 !important;-webkit-flex-shrink:1 !important;flex-shrink:1 !important}
+.rn-bottom-1p0dtai{bottom:0px}
+.rn-left-1d2f490{left:0px}
+.rn-position-u8s1d{position:absolute}
+.rn-right-zchlnj{right:0px}
+.rn-top-ipm5af{top:0px}
+.rn-pointerEvents-12vffkv > *{pointer-events:auto}
+.rn-pointerEvents-12vffkv{pointer-events:none !important}"
+`;
diff --git a/packages/react-native-web/src/exports/AppRegistry/__tests__/renderApplication-test.js b/packages/react-native-web/src/exports/AppRegistry/__tests__/renderApplication-test.js
index 80d7c02f..6fcd8b63 100644
--- a/packages/react-native-web/src/exports/AppRegistry/__tests__/renderApplication-test.js
+++ b/packages/react-native-web/src/exports/AppRegistry/__tests__/renderApplication-test.js
@@ -1,19 +1,61 @@
/* eslint-env jasmine, jest */
+import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';
import { getApplication } from '../renderApplication';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
+import { render } from 'enzyme';
+import StyleSheet from '../../StyleSheet';
+import View from '../../View';
const RootComponent = () =>
;
-describe('apis/AppRegistry/renderApplication', () => {
- test('getApplication', () => {
- const { element, stylesheets } = getApplication(RootComponent, {});
+describe('AppRegistry/renderApplication', () => {
+ describe('getApplication', () => {
+ const canUseDOM = ExecutionEnvironment.canUseDOM;
- expect(element).toMatchSnapshot();
- stylesheets.forEach(sheet => {
- const result = ReactDOMServer.renderToStaticMarkup(sheet);
- expect(result).toMatchSnapshot();
+ beforeEach(() => {
+ ExecutionEnvironment.canUseDOM = false;
+ });
+
+ afterEach(() => {
+ ExecutionEnvironment.canUseDOM = canUseDOM;
+ });
+
+ test('returns "element" and "getStyleElement"', () => {
+ const { element, getStyleElement } = getApplication(RootComponent, {});
+ expect(element).toMatchSnapshot();
+ expect(ReactDOMServer.renderToStaticMarkup(getStyleElement())).toMatchSnapshot();
+ });
+
+ test('"getStyleElement" produces styles that are a function of rendering "element"', () => {
+ const getTextContent = getStyleElement =>
+ getStyleElement().props.dangerouslySetInnerHTML.__html;
+
+ // First "RootComponent" render
+ let app = getApplication(RootComponent, {});
+ render(app.element);
+ const first = getTextContent(app.getStyleElement);
+
+ // Next render is a different tree; the style sheet should be different
+ const styles = StyleSheet.create({ root: { borderWidth: 1234, backgroundColor: 'purple' } });
+ app = getApplication(() => , {});
+ render(app.element);
+ const second = getTextContent(app.getStyleElement);
+
+ const diff = second.split(first)[1];
+
+ expect(first).toMatchSnapshot('CSS for an unstyled app');
+ expect(diff).toMatchSnapshot('Additional CSS for styled app');
+ expect(first).not.toEqual(second);
+
+ // Final render is once again "RootComponent"; the style sheet should not
+ // be polluted by earlier rendering of a different tree
+ app = getApplication(RootComponent, {});
+ render(app.element);
+ const third = getTextContent(app.getStyleElement);
+
+ expect(first).toEqual(third);
});
});
});
diff --git a/packages/react-native-web/src/exports/AppRegistry/renderApplication.js b/packages/react-native-web/src/exports/AppRegistry/renderApplication.js
index b0e5b5ac..44dd33fb 100644
--- a/packages/react-native-web/src/exports/AppRegistry/renderApplication.js
+++ b/packages/react-native-web/src/exports/AppRegistry/renderApplication.js
@@ -13,7 +13,7 @@ import AppContainer from './AppContainer';
import invariant from 'fbjs/lib/invariant';
import hydrate from '../../modules/hydrate';
import render from '../render';
-import StyleSheet from '../StyleSheet';
+import styleResolver from '../StyleSheet/styleResolver';
import React, { type ComponentType } from 'react';
const renderFn = process.env.NODE_ENV !== 'production' ? render : hydrate;
@@ -39,9 +39,10 @@ export function getApplication(RootComponent: ComponentType