Skip to content

Commit 50c79c4

Browse files
author
Anders Breid
authored
Enable / disable buttons when back end is down (#112)
GUI modifications: * Buttons that require back end to be up and running will now be disabled when back end is down. * A status text will be displayed when buttons are disabled hinting the user to switch back end or check if it is up. Test improvements: * Mocked back end status so buttons are enabled on subscription page. * Speeded up several steps in the subscription page, shortened test time to about 30% * Added mocks to prevent java to cast exceptions when back end was not found.
1 parent 9ec679b commit 50c79c4

File tree

9 files changed

+148
-37
lines changed

9 files changed

+148
-37
lines changed

src/functionaltest/java/com/ericsson/ei/frontend/SeleniumBaseClass.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
package com.ericsson.ei.frontend;
22

33
import static org.junit.Assert.fail;
4+
import static org.mockito.Mockito.when;
45

56
import java.io.File;
67
import java.io.IOException;
78
import java.nio.charset.StandardCharsets;
89
import java.nio.file.Files;
910
import java.nio.file.Paths;
1011

12+
import org.apache.http.HttpEntity;
13+
import org.apache.http.HttpVersion;
14+
import org.apache.http.client.ClientProtocolException;
15+
import org.apache.http.client.entity.EntityBuilder;
16+
import org.apache.http.client.methods.CloseableHttpResponse;
17+
import org.apache.http.entity.ContentType;
18+
import org.apache.http.impl.client.CloseableHttpClient;
19+
import org.apache.http.message.BasicStatusLine;
1120
import org.apache.tomcat.util.http.fileupload.FileUtils;
1221
import org.junit.After;
1322
import org.junit.Before;
1423
import org.junit.Ignore;
1524
import org.junit.runner.RunWith;
1625
import org.mockito.InjectMocks;
26+
import org.mockito.Mockito;
1727
import org.mockito.MockitoAnnotations;
1828
import org.openqa.selenium.firefox.FirefoxDriver;
1929
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,10 +61,10 @@ public class SeleniumBaseClass {
5161

5262
@Autowired
5363
private BackEndInstanceFileUtils backEndInstanceFileUtils;
54-
64+
5565
@Autowired
5666
protected BackEndInstancesUtils backEndInstancesUtils;
57-
67+
5868
@Before
5969
public void setUp() throws Exception {
6070
File tempFile = File.createTempFile("tempfile", ".json");
@@ -90,4 +100,30 @@ protected static String getJSONStringFromFile(String filepath) throws IOExceptio
90100
return new String(Files.readAllBytes(Paths.get(filepath)), StandardCharsets.UTF_8).replaceAll("[\\r\\n ]", "");
91101
}
92102

103+
protected void initBaseMocks(CloseableHttpClient mockedHttpClient) throws ClientProtocolException, IOException {
104+
CloseableHttpResponse responseData = createMockedHTTPResponse("\"\":\"\"", 200);
105+
Mockito.doReturn(responseData).when(mockedHttpClient)
106+
.execute(Mockito.argThat(request -> (request).getURI().toString().contains("/auth/checkStatus")));
107+
108+
Mockito.doReturn(responseData).when(mockedHttpClient)
109+
.execute(Mockito.argThat(request -> (request).getURI().toString().contains("/auth")));
110+
111+
Mockito.doReturn(responseData).when(mockedHttpClient)
112+
.execute(Mockito.argThat(request -> (request).getURI().toString().contains("/subscriptions")));
113+
114+
Mockito.doReturn(responseData).when(mockedHttpClient)
115+
.execute(Mockito.argThat(request -> (request).getURI().toString().contains("/rules/rule-check/testRulePageEnabled")));
116+
117+
}
118+
119+
private CloseableHttpResponse createMockedHTTPResponse(String message, int httpStatus) {
120+
HttpEntity entity = EntityBuilder.create().setText(message).setContentType(ContentType.APPLICATION_JSON)
121+
.build();
122+
CloseableHttpResponse mockedHttpResponse = Mockito.mock(CloseableHttpResponse.class);
123+
mockedHttpResponse.setEntity(entity);
124+
when(mockedHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(HttpVersion.HTTP_1_1, httpStatus, "DUMMYRIGHTNOW"));
125+
when(mockedHttpResponse.getEntity()).thenReturn(entity);
126+
return mockedHttpResponse;
127+
}
128+
93129
}

src/functionaltest/java/com/ericsson/ei/frontend/TestAlarm.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
package com.ericsson.ei.frontend;
22

3-
import com.ericsson.ei.frontend.pageobjects.IndexPage;
4-
import com.ericsson.ei.frontend.pageobjects.TestRulesPage;
5-
import org.junit.Test;
6-
import org.openqa.selenium.By;
3+
import static org.junit.Assert.assertTrue;
74

85
import java.io.IOException;
9-
import java.util.stream.IntStream;
106

11-
import static org.junit.Assert.assertTrue;
7+
import org.apache.http.impl.client.CloseableHttpClient;
8+
import org.junit.Test;
9+
import org.openqa.selenium.By;
10+
import org.springframework.boot.test.mock.mockito.MockBean;
11+
12+
import com.ericsson.ei.frontend.pageobjects.IndexPage;
13+
import com.ericsson.ei.frontend.pageobjects.TestRulesPage;
1214

1315
public class TestAlarm extends SeleniumBaseClass {
1416

17+
@MockBean
18+
protected CloseableHttpClient mockedHttpClient;
19+
1520
@Test
1621
public void testAlarm() throws IOException {
22+
initBaseMocks(mockedHttpClient);
23+
1724
//Load index page
1825
IndexPage indexPageObject = new IndexPage(null, driver, baseUrl);
1926
indexPageObject.loadPage();

src/functionaltest/java/com/ericsson/ei/frontend/TestRulesFunctionality.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717

1818
public class TestRulesFunctionality extends SeleniumBaseClass {
1919

20-
@MockBean
21-
protected CloseableHttpClient mockedHttpClient;
22-
2320
private static final String DOWNLOADED_RULES_TEMPLATE_FILE_PATH = String.join(
2421
File.separator, SeleniumConfig.getTempDownloadDirectory().getPath(), "rulesTemplate.json");
2522
private static final String RULES_TEMPLATE_FILE_PATH = String.join(
@@ -33,8 +30,12 @@ public class TestRulesFunctionality extends SeleniumBaseClass {
3330
private static final String AGGREGATED_OBJECT_FILE_PATH = String.join(
3431
File.separator, "src", "functionaltest", "resources", "responses", "AggregatedObjectResponse.json");
3532

33+
@MockBean
34+
protected CloseableHttpClient mockedHttpClient;
35+
3636
@Test
3737
public void testJourneyToFindAggregatedObjectButton() throws Exception {
38+
initBaseMocks(mockedHttpClient);
3839
// Load index page and wait for it to load
3940
IndexPage indexPageObject = new IndexPage(mockedHttpClient, driver, baseUrl);
4041
indexPageObject.loadPage();

src/functionaltest/java/com/ericsson/ei/frontend/TestSubscriptionHandling.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
public class TestSubscriptionHandling extends SeleniumBaseClass {
2020

21-
@MockBean
22-
protected CloseableHttpClient mockedHttpClient;
23-
2421
private static final String DOWNLOADED_TEMPLATE_FILE_PATH = String.join(File.separator,
2522
SeleniumConfig.getTempDownloadDirectory().getPath(), "subscriptionsTemplate.json");
2623
private static final String SUBSCRIPTION_TEMPLATE_FILE_PATH = String.join(File.separator, "src", "functionaltest",
@@ -36,8 +33,12 @@ public class TestSubscriptionHandling extends SeleniumBaseClass {
3633

3734
private JavascriptExecutor js;
3835

36+
@MockBean
37+
protected CloseableHttpClient mockedHttpClient;
38+
3939
@Test
4040
public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
41+
initBaseMocks(mockedHttpClient);
4142
// Open index page.
4243
IndexPage indexPageObject = new IndexPage(mockedHttpClient, driver, baseUrl);
4344
indexPageObject.loadPage();
@@ -75,8 +76,8 @@ public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
7576
indexPageObject.clickSubscriptionPage();
7677

7778
assert (subscriptionPage.clickExpandButtonByXPath(expandButtonXPath));
78-
assert (!subscriptionPage.buttonExistByXPath(deleteButtonXPath));
79-
assert (!subscriptionPage.buttonExistByXPath(editButtonXPath));
79+
assert (subscriptionPage.buttonDoesNotExistByXPath(deleteButtonXPath));
80+
assert (subscriptionPage.buttonDoesNotExistByXPath(editButtonXPath));
8081
assert (subscriptionPage.buttonExistByXPath(viewButtonXPath));
8182

8283
// Given LDAP is enabled, "Reload" subscriptions and then click
@@ -108,8 +109,8 @@ public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
108109
assert (subscriptionPage.clickExpandButtonByXPath(expandButtonXPath2));
109110
assert (subscriptionPage.buttonExistByXPath(viewButtonXPath2));
110111
subscriptionPage.clickViewButtonByXPath(viewButtonXPath2);
111-
assert (!subscriptionPage.buttonExistByXPath(editButtonXPath2));
112-
assert (!subscriptionPage.buttonExistByXPath(deleteButtonXPath2));
112+
assert (subscriptionPage.buttonDoesNotExistByXPath(editButtonXPath2));
113+
assert (subscriptionPage.buttonDoesNotExistByXPath(deleteButtonXPath2));
113114

114115
// Test view button
115116
subscriptionPage.clickViewButtonByXPath(viewButtonXPath2);
@@ -125,8 +126,8 @@ public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
125126
// all subscriptions are deleted
126127
String mockedDeleteResponse = "";
127128
subscriptionPage.clickBulkDelete(mockedDeleteResponse);
128-
assert (!subscriptionPage.textExistsInTable("Subscription1"));
129-
assert (!subscriptionPage.textExistsInTable("Subscription2"));
129+
assert (subscriptionPage.textDoesNotExistsInTable("Subscription1"));
130+
assert (subscriptionPage.textDoesNotExistsInTable("Subscription2"));
130131

131132
// Verify that "get template" button works
132133
String mockedTemplateResponse = getJSONStringFromFile(SUBSCRIPTION_TEMPLATE_FILE_PATH);
@@ -146,7 +147,7 @@ public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
146147
// is open
147148
subscriptionPage.clickAddSubscription();
148149
String formHeaderID = "formHeader";
149-
assert ((new WebDriverWait(driver, 10).until((webdriver) -> subscriptionPage.presenceOfHeader(formHeaderID))));
150+
assert (subscriptionPage.presenceOfHeader(formHeaderID));
150151

151152
// On subscription form, select the template as "Mail Trigger" and
152153
// verify Test form "Cancel" button:Click "Cancel" button and verify
@@ -157,7 +158,7 @@ public void testSubscriptionHandlingWithLDAPEnabled() throws Exception {
157158
// Again, click "Add Subscription" button and verify that "Subscription
158159
// Form" is open
159160
subscriptionPage.clickAddSubscription();
160-
assert ((new WebDriverWait(driver, 10).until((webdriver) -> subscriptionPage.presenceOfHeader(formHeaderID))));
161+
assert (subscriptionPage.presenceOfHeader(formHeaderID));
161162

162163
// On subscription form, select the template as "Mail Trigger" and
163164
// verify

src/functionaltest/java/com/ericsson/ei/frontend/pageobjects/PageBaseClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class PageBaseClass {
2323
CloseableHttpResponse mockedHttpResponse;
2424
protected FirefoxDriver driver;
2525
protected String baseUrl;
26-
protected final int TIMEOUT_TIMER = 11;
26+
protected final int TIMEOUT_TIMER = 10;
2727

2828
public PageBaseClass(CloseableHttpClient mockedHttpClient, FirefoxDriver driver, String baseUrl) {
2929
super();

src/functionaltest/java/com/ericsson/ei/frontend/pageobjects/SubscriptionPage.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,26 @@ public boolean buttonExistByXPath(String XPath) {
243243
return false;
244244
}
245245

246+
public boolean buttonDoesNotExistByXPath(String XPath) {
247+
// The row indicates weather or not the del / view and edit buttons has moved down to
248+
// next row.
249+
String findInRow;
250+
try {
251+
findInRow = "[2]";
252+
new WebDriverWait(driver, TIMEOUT_TIMER).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(XPath + findInRow)));
253+
} catch (Exception e) {
254+
return false;
255+
}
256+
try {
257+
findInRow = "[1]";
258+
new WebDriverWait(driver, TIMEOUT_TIMER).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(XPath + findInRow)));
259+
} catch (Exception e) {
260+
return false;
261+
}
262+
//elementIsNotVisible
263+
return true;
264+
}
265+
246266
public void clickReloadLDAP(String response, String responseAuth) throws IOException {
247267
CloseableHttpResponse responseData = this.createMockedHTTPResponse(response, 200);
248268
CloseableHttpResponse responseDataAuth = this.createMockedHTTPResponse(responseAuth, 200);
@@ -264,6 +284,15 @@ public boolean textExistsInTable(String txt) {
264284
return true;
265285
}
266286

287+
public boolean textDoesNotExistsInTable(String txt) {
288+
try {
289+
new WebDriverWait(driver, TIMEOUT_TIMER).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//tr[td[contains(.,'" +txt+ "')]]")));
290+
} catch (Exception e) {
291+
return false;
292+
}
293+
return true;
294+
}
295+
267296
public boolean clickExpandButtonByXPath(String loc) {
268297
try {
269298
if (expandButtonExist(loc)) {

src/main/resources/static/css/style.css

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ body {
7272
align-items: center;
7373
flex-flow: column;
7474
}
75-
.subButtons {
75+
.hidden_by_default {
7676
display: none;
7777
}
7878
.loader {
@@ -129,7 +129,13 @@ body {
129129
position: absolute;
130130
left: -999em;
131131
}
132-
132+
.flex-wrap {
133+
flex-wrap: wrap;
134+
}
135+
#back_end_down_warning {
136+
font-size: 12pt;
137+
color: #dc3545;
138+
}
133139
/* The switch - the box around the slider */
134140
.switch {
135141
position: relative;

src/main/resources/static/js/subscription.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ jQuery(document).ready(function () {
9292
// Check if EI Backend Server is online every X seconds
9393
window.setInterval(function () { checkBackendStatus(); }, 15000);
9494

95+
// Check if buttons should be enabled or disabled
96+
// Execute code to show or hide status enable disable buttons
97+
var buttonsDisabled = false;
98+
window.setInterval(function () {
99+
if (!backendStatus && !buttonsDisabled) {
100+
$("#back_end_down_warning").show();
101+
$(".hidden_by_default").show();
102+
buttonsDisabled = true;
103+
toggleButtonsDisabled(buttonsDisabled);
104+
} else if (backendStatus && buttonsDisabled) {
105+
$("#back_end_down_warning").hide();
106+
buttonsDisabled = false;
107+
toggleButtonsDisabled(buttonsDisabled);
108+
reload_table();
109+
}
110+
}, 1000);
111+
95112
// Check if EI Backend Server is online when Status Connection button is pressed.
96113
$("#btnEIConnection").click(function () {
97114
checkBackendStatus();
@@ -434,11 +451,11 @@ jQuery(document).ready(function () {
434451
"render": function (data, type, row, meta) {
435452

436453
if (isSecured == false || (row.ldapUserName == currentUser && row.ldapUserName != null)) {
437-
return '<button id="view-' + data.subscriptionName + '" class="btn btn-sm btn-success view_record">View</button> '
438-
+ '<button id="edit-' + data.subscriptionName + '" class="btn btn-sm btn-primary edit_record">Edit</button> '
439-
+ '<button id="delete-' + data.subscriptionName + '" class="btn btn-sm btn-danger delete_record">Delete</button>';
454+
return '<button id="view-' + data.subscriptionName + '" class="btn btn-sm btn-success view_record table-btn">View</button> '
455+
+ '<button id="edit-' + data.subscriptionName + '" class="btn btn-sm btn-primary edit_record table-btn">Edit</button> '
456+
+ '<button id="delete-' + data.subscriptionName + '" class="btn btn-sm btn-danger delete_record table-btn">Delete</button>';
440457
} else {
441-
return '<button id="view-' + data.subscriptionName + '" class="btn btn-sm btn-success view_record">View</button>';
458+
return '<button id="view-' + data.subscriptionName + '" class="btn btn-sm btn-success view_record table-btn">View</button>';
442459
}
443460
}
444461
}
@@ -988,8 +1005,17 @@ jQuery(document).ready(function () {
9881005
// Delay display buttons
9891006
setTimeout(showButtons, 800);
9901007
function showButtons() {
991-
$(".loadingAnimation").hide();
992-
$(".subButtons").show();
1008+
$("#loadingAnimation").hide();
1009+
$("#subButtons").show();
1010+
}
1011+
1012+
function toggleButtonsDisabled(disabled) {
1013+
$('#addSubscription').prop("disabled", disabled);
1014+
$('#bulkDelete').prop("disabled", disabled);
1015+
$('#uploadSubscription').prop("disabled", disabled);
1016+
$('#getTemplateButton').prop("disabled", disabled);
1017+
$('#reloadButton').prop("disabled", disabled);
1018+
$('.table-btn').prop("disabled", disabled);
9931019
}
9941020

9951021
function loadTooltip() {

src/main/resources/templates/subscription.html

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@
1515

1616
<body>
1717
<div class="d-none" id="subscriptionTemplate" th:text="${subscriptionTemplate}"></div>
18-
<div class="d-flex">
19-
<div class="col-md-9 col-8">
18+
<div class="d-flex flex-wrap">
19+
<div class="col-md-4 col-6 order-md-0">
2020
<h3>Eiffel Intelligence Subscription Handling</h3>
2121
</div>
22-
<div class="col-md-3 col-4 d-flex justify-content-end">
22+
<div class="col-md-6 col-12 order-last order-md-1">
23+
<span id="back_end_down_warning" class="hidden_by_default">
24+
Ensure back end is up or switch to another back end before continuing!
25+
</span>
26+
</div>
27+
<div class="col-md-2 col-6 order-md-2 d-flex justify-content-end">
2328
<div id="btnEIContainer">
2429
<button title="EI connection status check is refreshed continuously. Click button to force check status."
2530
type="button" id="btnEIConnection" class="btn btnEIConnectionStatus white-space-normal">
@@ -33,7 +38,7 @@ <h3>Eiffel Intelligence Subscription Handling</h3>
3338
<div class="pb-2">
3439
<h3 id="subData">Subscription Data</h3>
3540
</div>
36-
<div class="pb-1 col-12 subButtons">
41+
<div id="subButtons" class="pb-1 col-12 hidden_by_default">
3742
<button id="addSubscription" class="mt-1 btn btn-success add_subscription show_if_authorized">
3843
<i class="glyphicon glyphicon-plus"></i> Add Subscription
3944
</button>
@@ -51,7 +56,7 @@ <h3 id="subData">Subscription Data</h3>
5156
</button>
5257
<input class="hide" type='file' id='upload_sub' name='file'/>
5358
</div>
54-
<div class="pb-1 col-12 loadingAnimation">
59+
<div id="loadingAnimation" class="pb-1 col-12">
5560
<!-- This div is the animated loading indicator -->
5661
<div class="loader"></div>
5762
</div>
@@ -374,4 +379,4 @@ <h5 class="d-inline">AND</h5>
374379

375380
</body>
376381

377-
</html>
382+
</html>

0 commit comments

Comments
 (0)