couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robertkowal...@apache.org
Subject [3/7] fauxton commit: updated refs/heads/master to 73521f1
Date Mon, 04 Jul 2016 13:29:33 GMT
Breadcrumbs React port: add breadcrumb component for simple header

PR: #732
PR-URL: https://github.com/apache/couchdb-fauxton/pull/732
Reviewed-By: garren smith <garren.smith@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/de9b12b3
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/de9b12b3
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/de9b12b3

Branch: refs/heads/master
Commit: de9b12b358425a5454ee7d4d0e1285a983a77891
Parents: 9c13fd4
Author: Robert Kowalski <rok@kowalski.gd>
Authored: Tue Jun 21 13:24:22 2016 +0200
Committer: Robert Kowalski <robertkowalski@apache.org>
Committed: Mon Jul 4 15:25:28 2016 +0200

----------------------------------------------------------------------
 Gruntfile.js                                    |   3 +-
 app/addons/components/actions.js                |  10 ++
 app/addons/components/actiontypes.js            |   3 +-
 .../components/assets/less/components.less      |   1 +
 .../assets/less/header-breadcrumbs.less         |  34 +++++
 app/addons/components/header-breadcrumbs.jsx    |  71 ++++++++++
 app/addons/components/stores.js                 | 129 -------------------
 .../tests/headerBreadcrumbsSpec.react.jsx       | 101 +++++++++++++++
 .../documents/tests/nightwatch/cloneDoc.js      |  58 +++++++++
 .../tests/nightwatch/createsDocument.js         |   2 +-
 .../nightwatch/createsDocumentWithoutId.js      |   2 +-
 .../tests/nightwatch/editDocumentsFromView.js   |   7 +-
 .../tests/nightwatch/fixRegressionTableView.js  |   2 +-
 .../tests/nightwatch/navigateFromNewDoc.js      |   2 +-
 .../tests/nightwatch/selectDocViaTypeahead.js   |   1 -
 app/addons/fauxton/base.js                      |  21 +--
 app/addons/fauxton/tests/baseSpec.js            |  84 ------------
 app/addons/fauxton/tests/breadcrumbsSpec.js     |  86 -------------
 18 files changed, 300 insertions(+), 317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/Gruntfile.js
----------------------------------------------------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index 39ed769..f2cc6e1 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -220,7 +220,8 @@ module.exports = function (grunt) {
           src: initHelper.getFileList(['[Ss]pec.js'], [
             './app/core/**/*[Ss]pec.js',
             './app/addons/**/*[Ss]pec.js',
-            './app/addons/**/*[Ss]pec.react.jsx'
+            './app/addons/**/*[Ss]pec.react.jsx',
+            './app/addons/**/*[Ss]pec.jsx'
           ])
         },
         template: 'test/test.config.underscore'

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/components/actions.js b/app/addons/components/actions.js
index a2b5855..c9618aa 100644
--- a/app/addons/components/actions.js
+++ b/app/addons/components/actions.js
@@ -69,7 +69,17 @@ function deleteDatabase (dbId) {
   });
 }
 
+function setBreadCrumbs (crumbs) {
+  FauxtonAPI.dispatch({
+    type: ActionTypes.CMPNTS_BREADCRUMBS_SET_CRUMBS,
+    options: {
+      crumbs: crumbs
+    }
+  });
+}
+
 export default {
+  setBreadCrumbs: setBreadCrumbs,
   deleteDatabase: deleteDatabase,
   showDeleteDatabaseModal: showDeleteDatabaseModal,
   showAPIBarButton: showAPIBarButton,

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/components/actiontypes.js b/app/addons/components/actiontypes.js
index e1ce518..2940c51 100644
--- a/app/addons/components/actiontypes.js
+++ b/app/addons/components/actiontypes.js
@@ -15,5 +15,6 @@ export default {
   CMPNTS_HIDE_API_BAR_BUTTON: 'CMPNTS_HIDE_API_BAR_BUTTON',
   CMPNTS_UPDATE_API_BAR: 'CMPNTS_UPDATE_API_BAR',
   CMPNTS_SET_API_BAR_CONTENT_VISIBLE_STATE: 'CMPNTS_SET_API_BAR_CONTENT_VISIBLE_STATE',
-  CMPNTS_DATABASES_SHOWDELETE_MODAL: 'CMPNTS_DATABASES_SHOWDELETE_MODAL'
+  CMPNTS_DATABASES_SHOWDELETE_MODAL: 'CMPNTS_DATABASES_SHOWDELETE_MODAL',
+  CMPNTS_BREADCRUMBS_SET_CRUMBS: 'CMPNTS_BREADCRUMBS_SET_CRUMBS'
 };

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/assets/less/components.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/components.less b/app/addons/components/assets/less/components.less
index 0600d39..ac57783 100644
--- a/app/addons/components/assets/less/components.less
+++ b/app/addons/components/assets/less/components.less
@@ -22,3 +22,4 @@
 @import "modals.less";
 @import "tab-element.less";
 @import "left-header.less";
+@import "header-breadcrumbs.less";

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/assets/less/header-breadcrumbs.less
----------------------------------------------------------------------
diff --git a/app/addons/components/assets/less/header-breadcrumbs.less b/app/addons/components/assets/less/header-breadcrumbs.less
new file mode 100644
index 0000000..f419eb1
--- /dev/null
+++ b/app/addons/components/assets/less/header-breadcrumbs.less
@@ -0,0 +1,34 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+.faux-header__breadcrumbs {
+  .display-flex();
+}
+
+.faux-header__breadcrumbs-element {
+  margin: 0 4px 0 4px;
+  color: #333;
+  padding: 18px 10px;
+  font-size: 24px;
+  text-shadow: none;
+}
+
+.faux-header__breadcrumbs-link:hover {
+  text-decoration: none;
+  cursor: hand;
+}
+
+.faux-header__controlbox-backlink {
+  border-right: 1px solid #ccc;
+  padding-left: 10px;
+  padding-right: 2px;
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/header-breadcrumbs.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/header-breadcrumbs.jsx b/app/addons/components/header-breadcrumbs.jsx
new file mode 100644
index 0000000..c93561f
--- /dev/null
+++ b/app/addons/components/header-breadcrumbs.jsx
@@ -0,0 +1,71 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+export const Breadcrumbs = ({crumbs}) => {
+
+  const childs = getChildren(crumbs);
+
+  return (
+    <div className="faux-header__breadcrumbs">
+      {childs}
+    </div>
+  );
+
+};
+
+Breadcrumbs.propTypes = {
+  crumbs: React.PropTypes.array.isRequired
+};
+
+
+const CrumbElement = ({children}) => {
+  return <div className="faux-header__breadcrumbs-element">{children}</div>;
+};
+
+const Divider = () => {
+  const style = {width: '13px', paddingTop: '22px', fontSize: '20px'};
+  return (
+    <div
+      className="fonticon-right-open faux-header__breadcrumbs-divider"
+      style={style}></div>
+  );
+};
+
+function getChildren (crumbs) {
+  const amountDividers = crumbs.length - 1;
+
+  return crumbs.map((c, i) => {
+
+    let res = [<CrumbElement key={i}>{c.name}</CrumbElement>];
+
+    if (c.link) {
+      res = [
+        <CrumbElement key={i}>
+          <a className="faux-header__breadcrumbs-link" href={c.link}>{c.name}</a>
+        </CrumbElement>
+      ];
+    }
+
+    if (!c.name) {
+      return res;
+    }
+
+    if (i < amountDividers) {
+      res.push(<Divider />);
+    }
+
+    return res;
+  });
+}

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/components/stores.js b/app/addons/components/stores.js
deleted file mode 100644
index af5a69c..0000000
--- a/app/addons/components/stores.js
+++ /dev/null
@@ -1,129 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-import FauxtonAPI from "../../core/api";
-import app from "../../app";
-import ActionTypes from "./actiontypes";
-var Stores = {};
-
-Stores.ComponentStore = FauxtonAPI.Store.extend({
-  initialize: function () {
-    this.reset();
-  },
-
-  reset: function () {
-    this._apiBarVisible = false;
-    this._apiBarButtonVisible = true;
-    this._endpoint = '';
-    this._docURL = FauxtonAPI.constants.DOC_URLS.GENERAL;
-  },
-
-  updateAPIBar: function (settings) {
-    this._apiBarVisible = settings.contentVisible;
-    this._apiBarButtonVisible = settings.buttonVisible;
-    this._endpoint = settings.endpoint;
-    this._docURL = settings.docURL;
-  },
-
-  setVisibleButton: function (state) {
-    this._apiBarButtonVisible = state;
-  },
-
-  setApiBarVisible: function (state) {
-    this._apiBarVisible = state;
-  },
-
-  getEndpoint: function () {
-    return this._endpoint;
-  },
-
-  getDocURL: function () {
-    return this._docURL;
-  },
-
-  getIsAPIBarButtonVisible: function () {
-    return this._apiBarButtonVisible;
-  },
-
-  getIsAPIBarVisible: function () {
-    return this._apiBarVisible;
-  },
-
-  dispatch: function (action) {
-    switch (action.type) {
-      case ActionTypes.CMPNTS_SHOW_API_BAR_BUTTON:
-        this.setVisibleButton(true);
-      break;
-
-      case ActionTypes.CMPNTS_HIDE_API_BAR_BUTTON:
-        this.setVisibleButton(false);
-      break;
-
-      case ActionTypes.CMPNTS_SET_API_BAR_CONTENT_VISIBLE_STATE:
-        this.setApiBarVisible(action.options);
-      break;
-
-      case ActionTypes.CMPNTS_UPDATE_API_BAR:
-        this.updateAPIBar(action.options);
-      break;
-
-      default:
-      return;
-        // do nothing
-    }
-
-    this.triggerChange();
-  }
-});
-
-Stores.DeleteDbModalStore = FauxtonAPI.Store.extend({
-  initialize: function () {
-    this.reset();
-  },
-
-  reset: function () {
-    this._deleteModal = {showDeleteModal: false, dbId: '', isSystemDatabase: false};
-  },
-
-  setDeleteModal: function (options) {
-    options.isSystemDatabase = app.utils.isSystemDatabase(options.dbId);
-    this._deleteModal = options;
-  },
-
-  getShowDeleteDatabaseModal: function () {
-    return this._deleteModal;
-  },
-
-  dispatch: function (action) {
-    switch (action.type) {
-      case ActionTypes.CMPNTS_DATABASES_SHOWDELETE_MODAL:
-        this.setDeleteModal(action.options);
-      break;
-
-      default:
-      return;
-    }
-
-    this.triggerChange();
-  }
-});
-
-
-
-
-Stores.deleteDbModalStore = new Stores.DeleteDbModalStore();
-Stores.deleteDbModalStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.deleteDbModalStore.dispatch);
-
-Stores.componentStore = new Stores.ComponentStore();
-Stores.componentStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.componentStore.dispatch);
-
-export default Stores;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/components/tests/headerBreadcrumbsSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/components/tests/headerBreadcrumbsSpec.react.jsx b/app/addons/components/tests/headerBreadcrumbsSpec.react.jsx
new file mode 100644
index 0000000..b96cd08
--- /dev/null
+++ b/app/addons/components/tests/headerBreadcrumbsSpec.react.jsx
@@ -0,0 +1,101 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+import FauxtonAPI from '../../../core/api';
+import utils from '../../../../test/mocha/testUtils';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import TestUtils from 'react-addons-test-utils';
+
+import {Breadcrumbs} from '../header-breadcrumbs';
+
+const assert = utils.assert;
+
+describe('Breadcrumbs', () => {
+  let container;
+
+  beforeEach(() => {
+    container = document.createElement('div');
+  });
+
+  afterEach(() => {
+    ReactDOM.unmountComponentAtNode(container);
+  });
+
+  it('should not inject dividers if 1 element present', () => {
+
+    const crumbs = [{name: 'pineapple'}];
+
+    let el = TestUtils.renderIntoDocument(
+      <Breadcrumbs crumbs={crumbs} />,
+      container
+    );
+
+    const $node = $(ReactDOM.findDOMNode(el));
+
+    assert.equal($node.find('.faux-header__breadcrumbs-divider').length, 0);
+  });
+
+  it('should inject 2 dividers if 3 elements present', () => {
+
+    const crumbs = [
+      {name: 'pineapple'},
+      {name: 'mango'},
+      {name: 'guayaba'}
+    ];
+
+    let el = TestUtils.renderIntoDocument(
+      <Breadcrumbs crumbs={crumbs} />,
+      container
+    );
+
+    const $node = $(ReactDOM.findDOMNode(el));
+
+    assert.equal($node.find('.faux-header__breadcrumbs-divider').length, 2);
+  });
+
+  it('linked breadcrumbs are possible', () => {
+
+    const crumbs = [
+      {name: 'pineapple'},
+      {name: 'mango', link: 'http://example.com'},
+      {name: 'guayaba'}
+    ];
+
+    let el = TestUtils.renderIntoDocument(
+      <Breadcrumbs crumbs={crumbs} />,
+      container
+    );
+
+    const $node = $(ReactDOM.findDOMNode(el));
+
+    assert.equal($node.find('.faux-header__breadcrumbs-link').length, 1);
+  });
+
+  it('linked breadcrumbs are not created for non-linked elements', () => {
+
+    const crumbs = [
+      {name: 'pineapple'},
+      {name: 'mango'},
+      {name: 'guayaba'}
+    ];
+
+    let el = TestUtils.renderIntoDocument(
+      <Breadcrumbs crumbs={crumbs} />,
+      container
+    );
+
+    const $node = $(ReactDOM.findDOMNode(el));
+
+    assert.equal($node.find('.faux-header__breadcrumbs-link').length, 3);
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/cloneDoc.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/cloneDoc.js b/app/addons/documents/tests/nightwatch/cloneDoc.js
new file mode 100644
index 0000000..70988db
--- /dev/null
+++ b/app/addons/documents/tests/nightwatch/cloneDoc.js
@@ -0,0 +1,58 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+
+module.exports = {
+  'Deletes a document via Editor': function (client) {
+    const waitTime = client.globals.maxWaitTime;
+    const newDatabaseName = client.globals.testDatabaseName;
+    const newDocumentName = 'clone_doc_doc';
+    const baseUrl = client.globals.test_settings.launch_url;
+
+    client
+      .createDocument(newDocumentName, newDatabaseName)
+      .checkForDocumentCreated(newDocumentName)
+      .loginToGUI()
+
+      .url(baseUrl + '#/database/' + newDatabaseName + '/' + newDocumentName)
+      .waitForElementPresent('#editor-container', waitTime, false)
+      .clickWhenVisible('#doc-editor-actions-panel button[title="Clone Document"]')
+
+      .waitForElementVisible('.clone-doc-modal input', waitTime, false)
+
+      .clickWhenVisible('.clone-doc-modal input')
+
+      .clearValue('.clone-doc-modal input')
+      .setValue('.clone-doc-modal input', ['ente'])
+
+      .clickWhenVisible('.clone-doc-modal button.btn.btn-success')
+      .closeNotification()
+
+      .waitForAttribute('.faux-header__breadcrumbs .faux-header__breadcrumbs-element:last-child',
'textContent', function (docContents) {
+        console.log(docContents);
+        return 'ente' === docContents.trim();
+      })
+
+      .url(`${baseUrl}'/'${newDatabaseName}/${newDocumentName}`)
+      .waitForElementPresent('#editor-container', waitTime, false)
+      .getText('#editor-container', function (result) {
+        const data = result.value;
+        const isCreatedDocumentPresent = data.indexOf('ente') !== -1;
+
+        this.verify.ok(
+          isCreatedDocumentPresent,
+          'Checking if new document no longer shows up in _all_docs.'
+        );
+      })
+    .end();
+  },
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/createsDocument.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/createsDocument.js b/app/addons/documents/tests/nightwatch/createsDocument.js
index 00586ec..444e915 100644
--- a/app/addons/documents/tests/nightwatch/createsDocument.js
+++ b/app/addons/documents/tests/nightwatch/createsDocument.js
@@ -31,7 +31,7 @@ module.exports = {
       .waitForElementPresent('.ace_gutter-active-line', waitTime, false)
 
       // confirm the header elements are showing up
-      .waitForElementVisible('.js-lastelement', waitTime, true)
+      .waitForElementVisible('.faux-header__breadcrumbs', waitTime, true)
       .waitForElementVisible('#api-navbar', waitTime, true)
 
       .execute('\

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/createsDocumentWithoutId.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/createsDocumentWithoutId.js b/app/addons/documents/tests/nightwatch/createsDocumentWithoutId.js
index 9fd8992..4f0bfd9 100644
--- a/app/addons/documents/tests/nightwatch/createsDocumentWithoutId.js
+++ b/app/addons/documents/tests/nightwatch/createsDocumentWithoutId.js
@@ -32,7 +32,7 @@ module.exports = {
       .waitForElementPresent('.ace_gutter-active-line', waitTime, false)
 
       // confirm the header elements are showing up
-      .waitForElementVisible('.js-lastelement', waitTime, true)
+      .waitForElementVisible('.faux-header__breadcrumbs', waitTime, true)
       .waitForElementVisible('#api-navbar', waitTime, true)
 
       .execute('\

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/editDocumentsFromView.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/editDocumentsFromView.js b/app/addons/documents/tests/nightwatch/editDocumentsFromView.js
index 154ee3f..25e9210 100644
--- a/app/addons/documents/tests/nightwatch/editDocumentsFromView.js
+++ b/app/addons/documents/tests/nightwatch/editDocumentsFromView.js
@@ -38,17 +38,18 @@ module.exports = {
       .clickWhenVisible('#nav-design-function-abcviews a')
       .clickWhenVisible('#abc_evens')
       .clickWhenVisible('a[href="#/database/fauxton-selenium-tests/document_10"]')
-
       //navigated to editor
       .waitForElementVisible('#editor-container', waitTime, false)
       .verify.urlContains('#/database/' + newDatabaseName + '/document_10');
   },
 
   'Edit is not allowed for Map Views where reduce is checked' : function (client) {
-    var waitTime = client.globals.maxWaitTime;
+    const waitTime = client.globals.maxWaitTime;
+    const baseUrl = client.globals.test_settings.launch_url;
+    const newDatabaseName = client.globals.testDatabaseName;
 
     client
-      .clickWhenVisible('#dashboard a[href="#database/fauxton-selenium-tests/_design/abc/_view/evens"]')
+      .url(baseUrl + '/#/database/' + newDatabaseName + '/_design/abc/_view/evens')
       .clickWhenVisible('.control-toggle-queryoptions')
       .clickWhenVisible('#query-options-tray label[for="qoReduce"]')
       .clickWhenVisible('#button-options button[type="submit"]')

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/fixRegressionTableView.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/fixRegressionTableView.js b/app/addons/documents/tests/nightwatch/fixRegressionTableView.js
index e691289..b697b20 100644
--- a/app/addons/documents/tests/nightwatch/fixRegressionTableView.js
+++ b/app/addons/documents/tests/nightwatch/fixRegressionTableView.js
@@ -30,7 +30,7 @@ module.exports = {
       .url(baseUrl + '/#/database/' + newDatabaseName + '/_all_docs')
 
       .clickWhenVisible('.fonticon-pencil', client.globals.maxWaitTime, false)
-      .clickWhenVisible('.fonticon-left-open', client.globals.maxWaitTime, false)
+      .clickWhenVisible('.faux-header__breadcrumbs-link')
       .clickWhenVisible('.fonticon-table', client.globals.maxWaitTime, false)
       .waitForElementVisible('.tableview-checkbox-cell', client.globals.maxWaitTime, false)
       .waitForElementVisible('.tableview-data-cell-id', client.globals.maxWaitTime, false)

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/navigateFromNewDoc.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/navigateFromNewDoc.js b/app/addons/documents/tests/nightwatch/navigateFromNewDoc.js
index 0115a3e..0f51deb 100644
--- a/app/addons/documents/tests/nightwatch/navigateFromNewDoc.js
+++ b/app/addons/documents/tests/nightwatch/navigateFromNewDoc.js
@@ -32,7 +32,7 @@ module.exports = {
       .verify.urlEquals(baseUrl + '/' + newLink)
 
       // now redirect back to the all docs page and check it's loaded properly
-      .clickWhenVisible('.fonticon-left-open')
+      .clickWhenVisible('.faux-header__breadcrumbs-link')
       .verify.urlEquals(baseUrl + '/#database/' + newDatabaseName + '/_all_docs');
   }
 };

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/documents/tests/nightwatch/selectDocViaTypeahead.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/selectDocViaTypeahead.js b/app/addons/documents/tests/nightwatch/selectDocViaTypeahead.js
index 39703d7..032eb94 100644
--- a/app/addons/documents/tests/nightwatch/selectDocViaTypeahead.js
+++ b/app/addons/documents/tests/nightwatch/selectDocViaTypeahead.js
@@ -27,7 +27,6 @@ module.exports = {
       .keys(['\uE00C'])
       .waitForElementPresent('.prettyprint', waitTime, false)
       .waitForElementPresent('.documents-pagination', waitTime, false)
-      .waitForElementPresent('.breadcrumb .js-lastelement', waitTime, false)
       .click('.burger')
 
       // we need to explicitly show the doc field because it's hidden on Travis due to screen
width

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/fauxton/base.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/base.js b/app/addons/fauxton/base.js
index a907c03..8999bda 100644
--- a/app/addons/fauxton/base.js
+++ b/app/addons/fauxton/base.js
@@ -12,6 +12,8 @@
 
 import app from "../../app";
 import FauxtonAPI from "../../core/api";
+import React from "react";
+
 import Components from "./components";
 import NotificationComponents from "./notifications/notifications.react";
 import Actions from "./notifications/actions";
@@ -19,6 +21,8 @@ import NavbarReactComponents from "./navigation/components.react";
 import NavigationActions from "./navigation/actions";
 import ReactComponents from "../components/react-components.react";
 import ComponentActions from "../components/actions";
+import {Breadcrumbs} from '../components/header-breadcrumbs';
+
 import "./assets/less/fauxton.less";
 
 var Fauxton = FauxtonAPI.addon();
@@ -61,9 +65,8 @@ Fauxton.initialize = function () {
       contentVisible: false
     });
 
-    if (routeObject.get('apiUrl')) {
-      var apiAndDocs = routeObject.get('apiUrl');
-
+    const apiAndDocs = routeObject.get('apiUrl');
+    if (apiAndDocs) {
       ComponentActions.updateAPIBar({
         buttonVisible: true,
         contentVisible: false,
@@ -78,16 +81,18 @@ Fauxton.initialize = function () {
       routeObject.setComponent('#notification-center-btn', NotificationComponents.NotificationCenterButton);
     }
 
+    // XXX React softmigration, remove after full breadcrumb rewrite
     if (routeObject.overrideBreadcrumbs) { return; }
 
     FauxtonAPI.masterLayout.removeView('#breadcrumbs');
-    var crumbs = routeObject.get('crumbs');
+    const crumbs = routeObject.get('crumbs');
 
-    if (crumbs.length) {
-      FauxtonAPI.masterLayout.setView('#breadcrumbs', new Components.Breadcrumbs({
-        crumbs: crumbs
-      }), true).render();
+    if (!crumbs.length) {
+      return;
     }
+
+    ComponentActions.setBreadCrumbs(crumbs);
+    routeObject.setComponent('#breadcrumbs', Breadcrumbs, {crumbs: crumbs});
   });
 
   var primaryNavBarEl = $('#primary-navbar')[0];

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/fauxton/tests/baseSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/tests/baseSpec.js b/app/addons/fauxton/tests/baseSpec.js
deleted file mode 100644
index da124b2..0000000
--- a/app/addons/fauxton/tests/baseSpec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-import testUtils from "../../../../test/mocha/testUtils";
-import FauxtonAPI from "../../../core/api";
-import Base from "../base";
-import Backbone from "backbone";
-import sinon from "sinon";
-var assert = testUtils.assert;
-
-
-describe('Fauxton RouteObject:beforeEstablish', function () {
-  var TestRouteObject, testRouteObject, mockLayout, _layout, setViewCalled;
-
-  before(function () {
-    Base.initialize();
-    _layout = FauxtonAPI.masterLayout;
-    setViewCalled = false;
-  });
-
-  beforeEach(function () {
-    TestRouteObject = FauxtonAPI.RouteObject.extend({
-      crumbs: ['mycrumbs'],
-      hideNotificationCenter: true
-    });
-
-    testRouteObject = new TestRouteObject();
-    var apiBar = {};
-    apiBar.hide = sinon.spy();
-
-    // Need to find a better way of doing this
-    mockLayout = {
-      setTemplate: function () {
-        var promise = $.Deferred();
-        promise.resolve();
-        return promise;
-      },
-      clearBreadcrumbs: sinon.spy(),
-      setView: function () {
-        return {
-          render: function () {
-            setViewCalled = true;
-          }
-        };
-      },
-      renderView: function () {
-        var d = $.Deferred();
-        d.resolve();
-        return d.promise();
-      },
-      removeView: sinon.spy(),
-      hooks: [],
-      setBreadcrumbs: sinon.spy(),
-      apiBar: apiBar,
-      layout: {
-        setView: function () {}
-      }
-    };
-  });
-
-  after(function () {
-    FauxtonAPI.masterLayout = _layout;
-  });
-
-  it('Should clear breadcrumbs', function () {
-    FauxtonAPI.masterLayout = mockLayout;
-    testRouteObject.renderWith('the-route', mockLayout, 'args');
-    assert.ok(mockLayout.removeView.calledWith('#breadcrumbs'), 'Clear Breadcrumbs called');
-  });
-
-  it('Should set breadcrumbs when breadcrumbs exist', function () {
-    FauxtonAPI.masterLayout = mockLayout;
-    testRouteObject.renderWith('the-route', mockLayout, 'args');
-    assert.ok(setViewCalled, 'Set Breadcrumbs was called');
-  });
-});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/de9b12b3/app/addons/fauxton/tests/breadcrumbsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/tests/breadcrumbsSpec.js b/app/addons/fauxton/tests/breadcrumbsSpec.js
deleted file mode 100644
index 3becca9..0000000
--- a/app/addons/fauxton/tests/breadcrumbsSpec.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-import FauxtonAPI from "../../../core/api";
-import Fauxton from "../base";
-import testUtils from "../../../../test/mocha/testUtils";
-import sinon from "sinon";
-var assert = testUtils.assert;
-
-describe('Breadcrumbs', function () {
-
-  describe('can be overriden in routeObject', function () {
-    var routeObj;
-
-    beforeEach(function () {
-      var RouteObj = FauxtonAPI.RouteObject.extend({
-        overrideBreadcrumbs: true,
-        crumbs: ["crumb"]
-      });
-      routeObj = new RouteObj({});
-    });
-
-    it('should not remove old breadcrumbs', function () {
-      var removeViewSpy = sinon.spy(FauxtonAPI.masterLayout, 'removeView');
-
-      routeObj.triggerBroadcast('beforeEstablish');
-      assert.notOk(removeViewSpy.called);
-      FauxtonAPI.masterLayout.removeView.restore();
-    });
-  });
-
-  //Breadcrumbs are create and managed in Fauxton/base.js
-  //If the route object has a crumbs function a breadcrumbs view is created
-  //and rendered on the page in #breadcrumbs
-  describe('Auto creation of breadcrumbs', function () {
-    var routeObj;
-
-    beforeEach(function () {
-      var RouteObj = FauxtonAPI.RouteObject.extend({
-        crumbs: ["crumb1", "crumb2"]
-      });
-      routeObj = new RouteObj({});
-    });
-
-    afterEach(function () {
-      if (FauxtonAPI.masterLayout.removeView.restore) {
-        FauxtonAPI.masterLayout.removeView.restore();
-      }
-
-      if (FauxtonAPI.masterLayout.setView.restore) {
-        FauxtonAPI.masterLayout.setView.restore();
-      }
-    });
-
-    it('should remove old breadcrumbs', function () {
-      var removeViewSpy = sinon.spy(FauxtonAPI.masterLayout, 'removeView');
-
-      routeObj.triggerBroadcast('beforeEstablish');
-      assert.ok(removeViewSpy.called);
-    });
-
-    it('should create new breadcrumbs', function () {
-      var setViewSpy = sinon.spy(FauxtonAPI.masterLayout, 'setView');
-
-      routeObj.triggerBroadcast('beforeEstablish');
-      assert.equal(setViewSpy.getCall(0).args[0], '#breadcrumbs');
-    });
-
-    it('should not create new breadcrumbs when no crumbs are on routeObject', function ()
{
-      var removeViewSpy = sinon.spy(FauxtonAPI.masterLayout, 'setView');
-      routeObj.crumbs = [];
-      routeObj.triggerBroadcast('beforeEstablish');
-
-      assert.notOk(removeViewSpy.called);
-    });
-
-  });
-});


Mime
View raw message