diff --git a/dashboard/src/pages/MonitorView.js b/dashboard/src/pages/MonitorView.js
index e662cd73db..68c57fa73e 100755
--- a/dashboard/src/pages/MonitorView.js
+++ b/dashboard/src/pages/MonitorView.js
@@ -31,7 +31,7 @@ import getParentRoute from '../utils/getParentRoute';
import { getProbes } from '../actions/probe';
import MSTeamsBox from '../components/webHooks/MSTeamsBox';
import SlackBox from '../components/webHooks/SlackBox';
-import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
+import { Tab, Tabs, TabList, TabPanel, resetIdCounter } from 'react-tabs';
import { fetchBasicIncidentSettings } from '../actions/incidentBasicsSettings';
class MonitorView extends React.Component {
@@ -40,6 +40,9 @@ class MonitorView extends React.Component {
super(props);
}
+ componentWillMount() {
+ resetIdCounter();
+ }
componentDidMount() {
if (SHOULD_LOG_ANALYTICS) {
logEvent(
diff --git a/dashboard/src/pages/Schedule.js b/dashboard/src/pages/Schedule.js
index 702bd01af7..59c8502dbf 100755
--- a/dashboard/src/pages/Schedule.js
+++ b/dashboard/src/pages/Schedule.js
@@ -71,6 +71,7 @@ class Schedule extends Component {
route={pathname}
name={name}
pageTitle="Schedule"
+ containerType="Call Schedule"
/>
diff --git a/dashboard/src/pages/ScheduledEventDetail.js b/dashboard/src/pages/ScheduledEventDetail.js
index e422905f8f..f5d452bbcd 100644
--- a/dashboard/src/pages/ScheduledEventDetail.js
+++ b/dashboard/src/pages/ScheduledEventDetail.js
@@ -112,6 +112,7 @@ class ScheduledEvent extends Component {
route={pathname}
name={eventName}
pageTitle="Scheduled Event Detail"
+ containerType="Scheduled Event"
/>
diff --git a/dashboard/src/pages/StatusPage.js b/dashboard/src/pages/StatusPage.js
index 0729b81f00..b95277b718 100755
--- a/dashboard/src/pages/StatusPage.js
+++ b/dashboard/src/pages/StatusPage.js
@@ -26,7 +26,7 @@ import {
import CustomStyles from '../components/statusPage/CustomStyles';
import BreadCrumbItem from '../components/breadCrumb/BreadCrumbItem';
import getParentRoute from '../utils/getParentRoute';
-import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
+import { Tab, Tabs, TabList, TabPanel, resetIdCounter } from 'react-tabs';
class StatusPage extends Component {
async componentDidMount() {
@@ -62,6 +62,9 @@ class StatusPage extends Component {
);
}
}
+ componentWillMount() {
+ resetIdCounter();
+ }
tabSelected = index => {
const tabSlider = document.getElementById('tab-slider');
tabSlider.style.transform = `translate(calc(${tabSlider.offsetWidth}px*${index}), 0px)`;
@@ -100,7 +103,7 @@ class StatusPage extends Component {
Basic
- Domain Settings
+ Custom Domains
Branding
diff --git a/dashboard/src/reducers/monitor.js b/dashboard/src/reducers/monitor.js
index d6065d0938..6783e0c893 100755
--- a/dashboard/src/reducers/monitor.js
+++ b/dashboard/src/reducers/monitor.js
@@ -1080,19 +1080,23 @@ export default function monitor(state = INITIAL_STATE, action) {
error: null,
success: true,
monitors: state.monitorsList.monitors.map(monitor => {
- if (
- monitor.monitors[0]._id === action.payload.monitorId
- ) {
- monitor.monitors[0].subscribers.subscribers = monitor.monitors[0].subscribers.subscribers.filter(
- subscriber =>
- subscriber._id !== action.payload._id
- );
- monitor.monitors[0].subscribers.count =
- monitor.monitors[0].subscribers.count - 1;
- return monitor;
- } else {
- return monitor;
- }
+ monitor.monitors.find((targetMonitor, index) => {
+ if (
+ targetMonitor._id === action.payload.monitorId
+ ) {
+ monitor.monitors[
+ index
+ ].subscribers.subscribers = monitor.monitors[
+ index
+ ].subscribers.subscribers.filter(
+ subscriber =>
+ subscriber._id !== action.payload._id
+ );
+ return true;
+ }
+ return false;
+ });
+ return monitor;
}),
},
});
diff --git a/dashboard/src/test/puppeteer/IncidentSubProject.test.js b/dashboard/src/test/puppeteer/IncidentSubProject.test.js
index 87456b91d8..5abd8954d2 100755
--- a/dashboard/src/test/puppeteer/IncidentSubProject.test.js
+++ b/dashboard/src/test/puppeteer/IncidentSubProject.test.js
@@ -252,6 +252,10 @@ describe('Incident API With SubProjects', () => {
);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
+
let type = 'internal';
// fill internal message thread form
await page.waitForSelector(`#add-${type}-message`);
@@ -336,6 +340,9 @@ describe('Incident API With SubProjects', () => {
await page.$eval(`#incident_${projectMonitorName1}_0`, e =>
e.click()
);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
await page.waitFor(2000);
for (let i = 0; i < 10; i++) {
@@ -352,6 +359,10 @@ describe('Incident API With SubProjects', () => {
await page.click(`#${type}-addButton`);
await page.waitFor(2000);
}
+ // click on incident timeline tab
+ await page.waitForSelector('#react-tabs-6');
+ await page.click('#react-tabs-6');
+ await page.waitFor(2000);
await page.waitForSelector(
'#incidentTimeline tr.incidentListItem'
diff --git a/dashboard/src/test/puppeteer/IncidentTimeline.test.js b/dashboard/src/test/puppeteer/IncidentTimeline.test.js
index e5dca08670..0cb28b09f9 100644
--- a/dashboard/src/test/puppeteer/IncidentTimeline.test.js
+++ b/dashboard/src/test/puppeteer/IncidentTimeline.test.js
@@ -11,7 +11,6 @@ const projectName = utils.generateRandomString();
const projectMonitorName = utils.generateRandomString();
const componentName = utils.generateRandomString();
-const bodyText = utils.generateRandomString();
const message = utils.generateRandomString();
describe('Incident Timeline API', () => {
@@ -70,136 +69,6 @@ describe('Incident Timeline API', () => {
await cluster.close();
});
- test(
- 'should create incident in project with multi-probes and add to incident timeline',
- async () => {
- expect.assertions(2);
- const testServer = async ({ page }) => {
- await page.goto(utils.HTTP_TEST_SERVER_URL + '/settings');
- await page.evaluate(
- () => (document.getElementById('responseTime').value = '')
- );
- await page.evaluate(
- () => (document.getElementById('statusCode').value = '')
- );
- await page.evaluate(
- () => (document.getElementById('body').value = '')
- );
- await page.waitForSelector('#responseTime');
- await page.$eval('input[name=responseTime]', e => e.click());
- await page.type('input[name=responseTime]', '0');
- await page.waitForSelector('#statusCode');
- await page.$eval('input[name=statusCode]', e => e.click());
- await page.type('input[name=statusCode]', '400');
- await page.select('#responseType', 'html');
- await page.waitForSelector('#body');
- await page.$eval('textarea[name=body]', e => e.click());
- await page.type(
- 'textarea[name=body]',
- `${bodyText}
`
- );
- await page.$eval('button[type=submit]', e => e.click());
- await page.waitForSelector('#save-btn');
- };
-
- const dashboard = async ({ page }) => {
- await page.waitFor(350000);
- // Navigate to Component details
- await init.navigateToComponentDetails(componentName, page);
-
- await page.waitForSelector('#incident_span_0');
-
- const incidentTitleSelector = await page.$('#incident_span_0');
-
- let textContent = await incidentTitleSelector.getProperty(
- 'innerText'
- );
- textContent = await textContent.jsonValue();
- expect(textContent.toLowerCase()).toEqual(
- `${projectMonitorName}'s Incident Status`.toLowerCase()
- );
-
- await page.waitForSelector(`#incident_${projectMonitorName}_0`);
- await page.$eval(`#incident_${projectMonitorName}_0`, e =>
- e.click()
- );
- await page.waitFor(5000);
-
- const incidentTimelineRows = await page.$$(
- '#incidentTimeline tr.incidentListItem'
- );
- const countIncidentTimelines = incidentTimelineRows.length;
- expect(countIncidentTimelines).toEqual(2);
- };
-
- await cluster.execute(null, testServer);
- await cluster.execute(null, dashboard);
- },
- operationTimeOut
- );
-
- test(
- 'should auto-resolve incident in project with multi-probes and add to incident timeline',
- async () => {
- expect.assertions(2);
- const testServer = async ({ page }) => {
- await page.goto(utils.HTTP_TEST_SERVER_URL + '/settings', {
- waitUntil: 'networkidle2',
- });
- await page.evaluate(
- () => (document.getElementById('responseTime').value = '')
- );
- await page.evaluate(
- () => (document.getElementById('statusCode').value = '')
- );
- await page.evaluate(
- () => (document.getElementById('body').value = '')
- );
- await page.waitForSelector('#responseTime');
- await page.$eval('input[name=responseTime]', e => e.click());
- await page.type('input[name=responseTime]', '0');
- await page.waitForSelector('#statusCode');
- await page.$eval('input[name=statusCode]', e => e.click());
- await page.type('input[name=statusCode]', '200');
- await page.select('#responseType', 'html');
- await page.waitForSelector('#body');
- await page.$eval('textarea[name=body]', e => e.click());
- await page.type(
- 'textarea[name=body]',
- `${bodyText}
`
- );
- await page.$eval('button[type=submit]', e => e.click());
- await page.waitForSelector('#save-btn');
- };
-
- const dashboard = async ({ page }) => {
- await page.waitFor(350000);
- // Navigate to Component details
- await init.navigateToComponentDetails(componentName, page);
-
- await page.waitForSelector('#ResolveText_0');
-
- const resolveTextSelector = await page.$('#ResolveText_0');
- expect(resolveTextSelector).not.toBeNull();
-
- await page.waitForSelector(`#incident_${projectMonitorName}_0`);
- await page.$eval(`#incident_${projectMonitorName}_0`, e =>
- e.click()
- );
- await page.waitFor(5000);
-
- const incidentTimelineRows = await page.$$(
- '#incidentTimeline tr.incidentListItem'
- );
- const countIncidentTimelines = incidentTimelineRows.length;
- expect(countIncidentTimelines).toEqual(6);
- };
-
- await cluster.execute(null, testServer);
- await cluster.execute(null, dashboard);
- },
- operationTimeOut
- );
test(
'should create incident in project and add to message to the incident message thread',
async () => {
@@ -210,28 +79,38 @@ describe('Incident Timeline API', () => {
await init.navigateToComponentDetails(componentName, page);
await page.waitForSelector(
- `#more-details-${projectMonitorName}`
- );
- await page.click(`#more-details-${projectMonitorName}`);
- // create incident
- await page.waitForSelector(
- `#monitorCreateIncident_${projectMonitorName}`
- );
- await page.click(
- `#monitorCreateIncident_${projectMonitorName}`
+ `#create_incident_${projectMonitorName}`
);
+ await page.click(`#create_incident_${projectMonitorName}`);
await page.waitForSelector('#createIncident');
await init.selectByText('#incidentType', 'Offline', page);
await page.type('#title', 'new incident');
+ await page.waitForSelector('#createIncident');
await page.click('#createIncident');
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(
+ `#more-details-${projectMonitorName}`
+ );
+ await page.click(`#more-details-${projectMonitorName}`);
+
+ await page.waitFor(2000);
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.click(`#incident_${projectMonitorName}_0`);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
+
// fill investigation message thread form
await page.waitFor(2000);
+ await page.waitForSelector(`#add-${type}-message`);
await page.click(`#add-${type}-message`);
await page.waitForSelector(
`#form-new-incident-${type}-message`
@@ -269,11 +148,24 @@ describe('Incident Timeline API', () => {
// Navigate to Component details
await init.navigateToComponentDetails(componentName, page);
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(
+ `#more-details-${projectMonitorName}`
+ );
+ await page.click(`#more-details-${projectMonitorName}`);
+
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.click(`#incident_${projectMonitorName}_0`);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
+
await page.waitForSelector(`#edit_${type}_incident_message_0`);
await page.click(`#edit_${type}_incident_message_0`);
await page.waitFor(5000);
@@ -312,10 +204,23 @@ describe('Incident Timeline API', () => {
await init.navigateToComponentDetails(componentName, page);
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(
+ `#more-details-${projectMonitorName}`
+ );
+ await page.click(`#more-details-${projectMonitorName}`);
+
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.click(`#incident_${projectMonitorName}_0`);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
// fill internal message thread form
await page.click(`#add-${type}-message`);
await page.waitForSelector(
@@ -357,16 +262,29 @@ describe('Incident Timeline API', () => {
await init.navigateToComponentDetails(componentName, page);
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(
+ `#more-details-${projectMonitorName}`
+ );
+ await page.click(`#more-details-${projectMonitorName}`);
+
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.click(`#incident_${projectMonitorName}_0`);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
await page.waitForSelector(`#edit_${type}_incident_message_0`);
await page.click(`#edit_${type}_incident_message_0`);
await page.waitFor(5000);
// edit investigation message thread form
- await page.waitForSelector(`#edit-${type}`);
+ await page.waitForSelector(`#${type}-editButton`);
await page.click(`textarea[id=edit-${type}]`);
await page.type(`textarea[id=edit-${type}]`, '-updated');
await init.selectByText(
@@ -403,10 +321,23 @@ describe('Incident Timeline API', () => {
await init.navigateToComponentDetails(componentName, page);
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(
+ `#more-details-${projectMonitorName}`
+ );
+ await page.click(`#more-details-${projectMonitorName}`);
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.click(`#incident_${projectMonitorName}_0`);
await page.waitFor(2000);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
+
await page.waitForSelector(
`#delete_${type}_incident_message_0`
);
@@ -438,10 +369,21 @@ describe('Incident Timeline API', () => {
await init.navigateToComponentDetails(componentName, page);
await page.waitFor(2000);
+ // navigate to monitor details
+ await page.waitForSelector(`#more-details-${projectMonitorName}`);
+ await page.click(`#more-details-${projectMonitorName}`);
+
+ // click on incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+
await page.waitForSelector(`#incident_${projectMonitorName}_0`);
await page.$eval(`#incident_${projectMonitorName}_0`, e =>
e.click()
);
+ // click on incident notes tab
+ await page.waitForSelector('#react-tabs-8');
+ await page.click('#react-tabs-8');
await page.waitFor(2000);
for (let i = 0; i < 10; i++) {
@@ -458,6 +400,11 @@ describe('Incident Timeline API', () => {
await page.waitFor(2000);
}
+ // click on timeline tab
+ await page.waitForSelector('#react-tabs-6');
+ await page.click('#react-tabs-6');
+ await page.waitFor(2000);
+
await page.waitForSelector('#incidentTimeline tr.incidentListItem');
let incidentTimelineRows = await page.$$(
'#incidentTimeline tr.incidentListItem'
@@ -466,14 +413,14 @@ describe('Incident Timeline API', () => {
expect(countIncidentTimelines).toEqual(10);
- const nextSelector = await page.$('#btnTimelineNext');
- await nextSelector.click();
+ await page.waitForSelector('#btnTimelineNext');
+ await page.click('#btnTimelineNext');
await page.waitFor(7000);
incidentTimelineRows = await page.$$(
'#incidentTimeline tr.incidentListItem'
);
countIncidentTimelines = incidentTimelineRows.length;
- expect(countIncidentTimelines).toEqual(6);
+ expect(countIncidentTimelines).toEqual(10);
const prevSelector = await page.$('#btnTimelinePrev');
await prevSelector.click();
diff --git a/dashboard/src/test/puppeteer/MonitorDetail.test.js b/dashboard/src/test/puppeteer/MonitorDetail.test.js
index 048103a417..d56af1d30c 100644
--- a/dashboard/src/test/puppeteer/MonitorDetail.test.js
+++ b/dashboard/src/test/puppeteer/MonitorDetail.test.js
@@ -146,8 +146,7 @@ describe('Monitor Detail API', () => {
await page.waitForSelector('#react-tabs-2');
await page.click('#react-tabs-2');
- const selector =
- 'tr.incidentListItem:first-of-type > td:nth-of-type(2)';
+ const selector = `#incident_${monitorName}_0`;
await page.waitForSelector(selector);
await page.click(selector);
await page.waitFor(3000);
@@ -265,8 +264,8 @@ describe('Monitor Detail API', () => {
await page.waitFor(5000);
// click on advance option tab
- await page.waitForSelector('#react-tabs-8');
- await page.click('#react-tabs-8');
+ await page.waitForSelector('#react-tabs-10');
+ await page.click('#react-tabs-10');
await page.waitForSelector('button[id=deleteIncidentButton]');
await page.$eval('#deleteIncidentButton', e => e.click());
@@ -277,11 +276,19 @@ describe('Monitor Detail API', () => {
await page.$eval('#confirmDeleteIncident', e => e.click());
await page.waitForNavigation();
- const incidentList = 'tr.incidentListItem';
- await page.waitForSelector(incidentList);
- await page.waitFor(35000);
+ // click on Incident tab
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
- expect((await page.$$(incidentList)).length).toEqual(0);
+ let incidentCountSpanElement = await page.waitForSelector(
+ `#incident_count`
+ );
+ incidentCountSpanElement = await incidentCountSpanElement.getProperty(
+ 'innerText'
+ );
+ incidentCountSpanElement = await incidentCountSpanElement.jsonValue();
+
+ expect(incidentCountSpanElement).toMatch('0 Incident');
});
},
operationTimeOut
diff --git a/dashboard/src/test/puppeteer/MonitorSubscribers.test.js b/dashboard/src/test/puppeteer/MonitorSubscribers.test.js
index 5404f6f3f5..d98974ef95 100644
--- a/dashboard/src/test/puppeteer/MonitorSubscribers.test.js
+++ b/dashboard/src/test/puppeteer/MonitorSubscribers.test.js
@@ -197,4 +197,40 @@ describe('Monitor Detail API', () => {
},
operationTimeOut
);
+
+ test(
+ 'Should delete a subscriber',
+ async () => {
+ return await cluster.execute(null, async ({ page }) => {
+ // Navigate to Monitor details
+ await init.navigateToMonitorDetails(
+ componentName,
+ monitorName,
+ page
+ );
+ // click on subscribers tab
+ await page.waitForSelector('#react-tabs-4');
+ await page.click('#react-tabs-4');
+
+ let initialSubscribers =
+ '#subscribersList > tbody > tr.subscriber-list-item';
+ await page.waitForSelector(initialSubscribers);
+ initialSubscribers = await page.$$(initialSubscribers);
+ const initialCount = initialSubscribers.length;
+
+ await page.waitForSelector('button[id=deleteSubscriber_0]');
+ await page.click('button[id=deleteSubscriber_0]');
+
+ let finalSubscribers =
+ '#subscribersList > tbody > tr.subscriber-list-item';
+ await page.waitForSelector(finalSubscribers);
+ finalSubscribers = await page.$$(finalSubscribers);
+ const finalCount = finalSubscribers.length;
+
+ expect(finalCount).toEqual(3);
+ expect(initialCount).toBeGreaterThan(finalCount);
+ });
+ },
+ operationTimeOut
+ );
});
diff --git a/dashboard/src/test/puppeteer/StatusPage.test.js b/dashboard/src/test/puppeteer/StatusPage.test.js
index e7412f84cc..649138dca1 100644
--- a/dashboard/src/test/puppeteer/StatusPage.test.js
+++ b/dashboard/src/test/puppeteer/StatusPage.test.js
@@ -60,6 +60,13 @@ describe('Status Page', () => {
//component + monitor
await init.addComponent(componentName, page);
await init.addMonitorToComponent(null, monitorName, page);
+ await page.goto(utils.DASHBOARD_URL);
+ await page.waitForSelector('#components', { visible: true });
+ await page.click('#components');
+ await page.waitForSelector(`#more-details-${componentName}`, {
+ visible: true,
+ });
+ await page.click(`#more-details-${componentName}`);
await init.addMonitorToComponent(null, monitorName1, page);
await page.waitForSelector('.ball-beat', { hidden: true });
}
@@ -381,8 +388,8 @@ describe('Status Page', () => {
await page.click('#react-tabs-2');
await page.waitForSelector('#addMoreDomain');
await page.click('#addMoreDomain');
- await page.waitForSelector('#domain', { visible: true });
- await page.type('#domain', 'fyipeapp.com');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'fyipeapp.com');
await page.click('#btnAddDomain');
// if domain was not added sucessfully, list will be undefined
// it will timeout
@@ -492,8 +499,8 @@ describe('Status Page', () => {
// create one more domain on the status page
await page.waitForSelector('#addMoreDomain');
await page.click('#addMoreDomain');
- await page.waitForSelector('#domain', { visible: true });
- await page.type('#domain', 'app.fyipeapp.com');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'app.fyipeapp.com');
await page.click('#btnAddDomain');
await page.reload({ waitUntil: 'networkidle0' });
@@ -539,8 +546,8 @@ describe('Status Page', () => {
// create one more domain on the status page
await page.waitForSelector('#addMoreDomain');
await page.click('#addMoreDomain');
- await page.waitForSelector('#domain', { visible: true });
- await page.type('#domain', 'app.fyipeapp.com');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'server.fyipeapp.com');
await page.click('#btnAddDomain');
await page.reload({ waitUntil: 'networkidle0' });
await page.waitForSelector('#react-tabs-2');
@@ -653,7 +660,7 @@ describe('Status Page', () => {
let elem = await page.$('#field-error');
elem = await elem.getProperty('innerText');
elem = await elem.jsonValue();
- expect(elem).toEqual('Domain is required');
+ expect(elem).toEqual('Domain is required.');
});
},
operationTimeOut
@@ -669,8 +676,8 @@ describe('Status Page', () => {
await page.click('#react-tabs-2');
await page.waitForSelector('#addMoreDomain');
await page.click('#addMoreDomain');
- await page.waitForSelector('#domain', { visible: true });
- await page.type('#domain', 'fyipeapp');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'fyipeapp');
await page.waitForSelector('#btnAddDomain');
await page.click('#btnAddDomain');
let elem = await page.$('#field-error');
@@ -681,4 +688,61 @@ describe('Status Page', () => {
},
operationTimeOut
);
+
+ test(
+ 'should add multiple domains',
+ async () => {
+ return await cluster.execute(null, async ({ page }) => {
+ await gotoTheFirstStatusPage(page);
+ await page.waitForNavigation({ waitUntil: 'networkidle0' });
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+ await page.waitForSelector('#addMoreDomain');
+ await page.click('#addMoreDomain');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'fyipe.fyipeapp.com');
+
+ await page.click('#addMoreDomain');
+ await page.waitForSelector('#domain_2', { visible: true });
+ await page.type('#domain_2', 'api.fyipeapp.com');
+ await page.waitForSelector('#btnAddDomain');
+ await page.click('#btnAddDomain');
+ await page.waitFor(10000);
+ const domains = await page.$$eval(
+ 'fieldset[name="added-domain"]',
+ domains => domains.length
+ );
+ expect(domains).toEqual(4);
+ });
+ },
+ operationTimeOut
+ );
+
+ test(
+ 'should not add an existing domain',
+ async () => {
+ return await cluster.execute(null, async ({ page }) => {
+ await gotoTheFirstStatusPage(page);
+ await page.waitForNavigation({ waitUntil: 'networkidle0' });
+ await page.waitForSelector('#react-tabs-2');
+ await page.click('#react-tabs-2');
+ const initialDomains = await page.$$eval(
+ 'fieldset[name="added-domain"]',
+ domains => domains.length
+ );
+ await page.waitForSelector('#addMoreDomain');
+ await page.click('#addMoreDomain');
+ await page.waitForSelector('#domain_1', { visible: true });
+ await page.type('#domain_1', 'fyipe.fyipeapp.com');
+ await page.click('#addMoreDomain');
+ await page.waitFor(5000);
+ const domains = await page.$$eval(
+ 'fieldset[name="added-domain"]',
+ domains => domains.length
+ );
+ expect(domains).toEqual(initialDomains);
+ });
+ },
+ operationTimeOut
+ );
});
diff --git a/git-hooks/README.md b/git-hooks/README.md
new file mode 100644
index 0000000000..9bb981e33f
--- /dev/null
+++ b/git-hooks/README.md
@@ -0,0 +1,14 @@
+# Hooks
+
+Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur. Hooks are triggered by operations such as committing and merging.
+
+This project has a git pre-commit hook that automatically runs when you execute `git commit`. This pre-commit is responsible for linting the project. This is one of the ways to be sure any code git committed has been linted properly.
+
+## Enable git hooks
+
+Run these command in your terminal from the root of this project.
+
+```
+root="$(pwd)"
+ln -s "$root/git-hooks" "$root/.git/hooks"
+```
diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit
new file mode 100644
index 0000000000..07a5297992
--- /dev/null
+++ b/git-hooks/pre-commit
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Run these command in your terminal from the root of this project.
+
+# ```
+# root="$(pwd)"
+# ln -s "$root/git-hooks" "$root/.git/hooks"
+# ```
+
+function jslint {
+ printf "\nValidating and Linting Javascript. This will take few minutes...\n"
+
+ npm run lint
+ if [[ "$?" != 0 ]]; then
+ printf "There are lint errors for your commit. Please run 'npm run fix-lint` to fix them.\n"
+ exit 1
+ fi
+ popd
+
+ printf "\nJavascript Validating and Linting Completed!\n"
+}
+
+jslint
\ No newline at end of file
diff --git a/smoke-test/home.test.js b/smoke-test/home.test.js
index 78e9682d05..b3b57e0760 100755
--- a/smoke-test/home.test.js
+++ b/smoke-test/home.test.js
@@ -49,7 +49,7 @@ describe('Request demo', () => {
await page.waitForSelector('#form-section');
await page.type('#fullname', util.user.name);
await page.type('#email', util.user.email);
- await page.type('#Phone', util.user.phone);
+ await page.type('#phone', util.user.phone);
await page.type('#website', util.user.website);
await page.click('#country');
await page.keyboard.press('ArrowDown');
@@ -74,7 +74,7 @@ describe('Request demo', () => {
await page.waitForSelector('#form-section');
await page.type('#fullname', util.user.name);
await page.type('#email', util.user.email);
- await page.type('#Phone', util.user.phone);
+ await page.type('#phone', util.user.phone);
await page.type('#website', util.user.website);
await page.click('#country');
await page.keyboard.press('ArrowDown');
@@ -99,7 +99,7 @@ describe('Request demo', () => {
await page.waitForSelector('#form-section');
await page.type('#fullname', util.user.name);
await page.type('#email', util.user.email);
- await page.type('#Phone', util.user.phone);
+ await page.type('#phone', util.user.phone);
await page.type('#website', util.user.website);
await page.click('#country');
await page.keyboard.press('ArrowDown');
@@ -124,7 +124,7 @@ describe('Request demo', () => {
await page.waitForSelector('#form-section');
await page.type('#fullname', util.user.name);
await page.type('#email', util.user.email);
- await page.type('#Phone', util.user.phone);
+ await page.type('#phone', util.user.phone);
await page.type('#website', util.user.website);
await page.click('#country');
await page.keyboard.press('ArrowDown');