Skip to content

Commit a2d1ca0

Browse files
committed
initial commit
0 parents  commit a2d1ca0

36 files changed

+6970
-0
lines changed

.babelrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"presets": [
3+
["@babel/preset-env", {
4+
"targets": {
5+
"browsers": ["last 2 versions", "Explorer 11"]
6+
}
7+
}],
8+
"@babel/preset-stage-0"
9+
]
10+
}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
debug.log

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# UI Testing Framework
2+
A simple testing framework with mocha, webdriver, and chai
3+
4+
# Get WebDriver
5+
You will need one of several drivers available for common browsers.
6+
https://www.npmjs.com/package/selenium-webdriver#installation
7+
8+
# Install
9+
$ npm i
10+
11+
# Test
12+
## Chrome Only
13+
14+
$ npm test
15+
16+
## Mac Browsers
17+
Chrome, Firefox, Safari
18+
19+
$ npm run test-mac
20+
21+
## Windows Browsers
22+
Chrome, Firefox, Edge, Internet Explorer
23+
24+
$ npm run test-win
25+
26+
## SauceLabs
27+
Chrome, Firefox, Safari, Edge, Internet Explorer
28+
29+
$ npm run test-sauce

index.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>React DOM Components Test</title>
6+
<meta name="description" content="A page for testing">
7+
<link rel="stylesheet" href="/sample/dist/css/styles.css"/>
8+
</head>
9+
<body>
10+
<img src="/sample/dist/img/rdc-icon.png" alt="React DOM Components" class="image" id="logo"/>
11+
<img src="/sample/dist/img/rdc-title.svg" alt="React DOM Components" class="image" id="title"/>
12+
<h1 class="hide-all">React DOM Components</h1>
13+
<h2 id="sub-title">Build data models for React Components using server-side DOM.</h2>
14+
<div class="container">
15+
<hr/>
16+
<rdc-section data-title="Problem">
17+
<p>Often times, using Node to render DOM server-side is not feasible. This could be due to technology, infrastructure, or even cache reasons. In these situations, one is left with either not using React or ignoring the initial server-side DOM. Both options have significant downsides.</p>
18+
</rdc-section>
19+
<rdc-section data-title="Solution">
20+
<p>React DOM Components are a technology agnostic way to get DOM properties and pass them in to React Components. By doing so, the initial render of a page can still be server-side (Java, .NET, PHP, etc.), but React can take over and provide the many features it does.</p>
21+
</rdc-section>
22+
<hr/>
23+
<h3 class="full-width">How They Work</h3>
24+
<img class="full-width" src="/sample/dist/img/rdc-works.svg" alt="React DOM Components" class="how-they-work"/>
25+
</div>
26+
<script src="/sample/dist/libs/nodelist-foreach.min.js" type="text/javascript"></script>
27+
<script src="/sample/dist/libs/custom-elements.min.js" type="text/javascript"></script>
28+
<script src="/sample/dist/index.js" type="text/javascript"></script>
29+
</body>
30+
</html>

index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const express = require('express');
2+
const app = express();
3+
4+
export default class WebServer {
5+
constructor() {
6+
app.use(express.static('.'));
7+
this.server = app.listen(3000, () => console.log('Listening on port 3000!'));
8+
}
9+
10+
close() {
11+
this.server.close(() => console.log('Closing port 3000!'));
12+
}
13+
}

lib/domcomponent/DOMComponent.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"use strict";
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = void 0;
7+
8+
var _react = _interopRequireDefault(require("react"));
9+
10+
var _reactDom = require("react-dom");
11+
12+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13+
14+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15+
16+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
17+
18+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
19+
20+
/**
21+
* The <code>DOMComponent</code> Class provides the properties
22+
* and methods to map a DOMModel to a React Component. It is
23+
* only rendered when the DOMRegistry provides the specific
24+
* element to render.
25+
*/
26+
var DOMComponent =
27+
/*#__PURE__*/
28+
function () {
29+
function DOMComponent() {
30+
_classCallCheck(this, DOMComponent);
31+
32+
this.nodeName = this.constructor.nodeName;
33+
this.model = this.constructor.model;
34+
this.component = this.constructor.component;
35+
}
36+
/**
37+
* Render the DOM Component into the supplied element.
38+
* @param {node} element
39+
*/
40+
41+
42+
_createClass(DOMComponent, [{
43+
key: "render",
44+
value: function render(element) {
45+
// Instantiate our DomModel
46+
var domModel = new this.model(element); // Set our properties
47+
48+
this.props = domModel.props; // Create our React element
49+
50+
var el = _react.default.createElement(this.component, this.props); // Render it
51+
52+
53+
(0, _reactDom.render)(el, element);
54+
}
55+
}]);
56+
57+
return DOMComponent;
58+
}();
59+
60+
exports.default = DOMComponent;

lib/dommodel/DOMModel.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"use strict";
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = void 0;
7+
8+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9+
10+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11+
12+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
13+
14+
/**
15+
* The <code>DomModel</code> Class creates a data model from
16+
* attributes, text, and children of a given element.
17+
*/
18+
var DOMModel =
19+
/*#__PURE__*/
20+
function () {
21+
function DOMModel(element) {
22+
_classCallCheck(this, DOMModel);
23+
24+
this.props = {};
25+
this.element = element;
26+
this.getId();
27+
this.getClassList();
28+
this.getChildNodes();
29+
}
30+
31+
_createClass(DOMModel, [{
32+
key: "getId",
33+
value: function getId() {
34+
this.props.id = this.element.id;
35+
}
36+
}, {
37+
key: "getClassList",
38+
value: function getClassList() {
39+
this.props.classList = this.element.classList;
40+
}
41+
}, {
42+
key: "getDataAttribute",
43+
value: function getDataAttribute(name) {
44+
this.props[name] = this.element.dataset[name];
45+
}
46+
}, {
47+
key: "getAttribute",
48+
value: function getAttribute(name) {
49+
this.props[name] = this.element.getAttribute(name);
50+
}
51+
}, {
52+
key: "getTextContent",
53+
value: function getTextContent() {
54+
var textNode = this.getChildNode('#text');
55+
56+
if (textNode !== null) {
57+
this.props['text'] = textNode.textContent;
58+
} else {
59+
this.props['text'] = null;
60+
}
61+
}
62+
}, {
63+
key: "getChildComponent",
64+
value: function getChildComponent(name, model) {
65+
var childElement = this.getChildNode(name);
66+
67+
if (childElement !== null) {
68+
this.props[name] = new model(childElement);
69+
} else {
70+
this.props[name] = null;
71+
}
72+
}
73+
}, {
74+
key: "getChildComponentArray",
75+
value: function getChildComponentArray(name, model) {
76+
this.props[name] = [];
77+
78+
for (var i = 0; i < this.nodes.length; ++i) {
79+
var nodeName = this.nodes[i].nodeName.toLowerCase();
80+
81+
if (nodeName === name) {
82+
this.props[name].push(new model(this.nodes[i]));
83+
}
84+
}
85+
}
86+
}, {
87+
key: "getChildNodes",
88+
value: function getChildNodes() {
89+
this.nodes = this.element.childNodes;
90+
}
91+
}, {
92+
key: "getChildNode",
93+
value: function getChildNode(name) {
94+
for (var i = 0; i < this.nodes.length; ++i) {
95+
var nodeName = this.nodes[i].nodeName.toLowerCase();
96+
97+
if (nodeName === name) {
98+
return this.nodes[i];
99+
}
100+
}
101+
102+
return null;
103+
}
104+
}]);
105+
106+
return DOMModel;
107+
}();
108+
109+
exports.default = DOMModel;

lib/domregistry/DOMRegistry.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"use strict";
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = void 0;
7+
8+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9+
10+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11+
12+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
13+
14+
/**
15+
* The <code>DOMRegistry</code> Class is used to register, find, and
16+
* render React DOM Components. It provides a mechanism to determine if
17+
* a registered DOM Component is a child of an existing DOM Component.
18+
*/
19+
var DOMRegistry =
20+
/*#__PURE__*/
21+
function () {
22+
function DOMRegistry(components) {
23+
_classCallCheck(this, DOMRegistry);
24+
25+
this.components = components;
26+
this.getNodeNames();
27+
this.init();
28+
}
29+
/**
30+
* Initialize the DOM Registry.
31+
*/
32+
33+
34+
_createClass(DOMRegistry, [{
35+
key: "init",
36+
value: function init() {
37+
var _this = this;
38+
39+
// Loop through all registred DOM Components
40+
this.components.forEach(function (component) {
41+
// Find all potential nodes of the components
42+
var componentNodes = document.querySelectorAll(component.nodeName); // Loop through each node and determine if we can render it.
43+
44+
componentNodes.forEach(function (componentNode) {
45+
var canRender = _this.traverseUpDom(componentNode);
46+
47+
if (canRender) {
48+
component.render(componentNode);
49+
}
50+
});
51+
});
52+
}
53+
/**
54+
* Create an array of element node names to look for.
55+
* @return {array} nodeNames
56+
*/
57+
58+
}, {
59+
key: "getNodeNames",
60+
value: function getNodeNames() {
61+
var _this2 = this;
62+
63+
this.nodeNames = {};
64+
this.components.forEach(function (component) {
65+
_this2.nodeNames[component.nodeName] = true;
66+
});
67+
}
68+
/**
69+
* Traverse up the DOM from the supplied node to see if any parents
70+
* are React DOM Components.
71+
* @return {boolean} canRender Whether the component can render with React.
72+
*/
73+
74+
}, {
75+
key: "traverseUpDom",
76+
value: function traverseUpDom(node) {
77+
var parentNode = node.parentNode; // If the DOM has already been swapped out by React, the parent node will be null.
78+
79+
if (parentNode !== null) {
80+
var parentNodeName = parentNode.nodeName.toLowerCase();
81+
82+
if (this.nodeNames[parentNodeName]) {
83+
return false;
84+
} else if (parentNodeName === 'body') {
85+
return true;
86+
} else {
87+
this.traverseUpDom(parentNode);
88+
return true;
89+
}
90+
} else {
91+
return false;
92+
}
93+
}
94+
}]);
95+
96+
return DOMRegistry;
97+
}();
98+
99+
exports.default = DOMRegistry;

lib/index.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use strict";
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
Object.defineProperty(exports, "DOMModel", {
7+
enumerable: true,
8+
get: function get() {
9+
return _DOMModel.default;
10+
}
11+
});
12+
Object.defineProperty(exports, "DOMComponent", {
13+
enumerable: true,
14+
get: function get() {
15+
return _DOMComponent.default;
16+
}
17+
});
18+
Object.defineProperty(exports, "DOMRegistry", {
19+
enumerable: true,
20+
get: function get() {
21+
return _DOMRegistry.default;
22+
}
23+
});
24+
25+
var _DOMModel = _interopRequireDefault(require("./dommodel/DOMModel"));
26+
27+
var _DOMComponent = _interopRequireDefault(require("./domcomponent/DOMComponent"));
28+
29+
var _DOMRegistry = _interopRequireDefault(require("./domregistry/DOMRegistry"));
30+
31+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

0 commit comments

Comments
 (0)