b83be2d721c14bd5655cf79bea1dab6002540e47
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/PageObject.java
| ... | ... | @@ -517,6 +517,11 @@ public class PageObject { |
| 517 | 517 | waitUntil((driver) -> supplier.getAsBoolean()); |
| 518 | 518 | } |
| 519 | 519 | |
| 520 | + protected void waitUntilAlertIsPresent() { |
|
| 521 | + WebDriverWait webDriverWait = new WebDriverWait(driver, DEFAULT_LOOKUP_TIMEOUT); |
|
| 522 | + webDriverWait.until(ExpectedConditions.alertIsPresent()); |
|
| 523 | + } |
|
| 524 | + |
|
| 520 | 525 | /** |
| 521 | 526 | * Returns a {@link PageArea} instance representing the element with the specified selenium id using the |
| 522 | 527 | * {@link WebDriver} as search context. |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/usermanagement/UserManagementPanelPO.java
| ... | ... | @@ -1,5 +1,9 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole.usermanagement; |
| 2 | 2 | |
| 3 | +import java.util.ArrayList; |
|
| 4 | +import java.util.List; |
|
| 5 | + |
|
| 6 | +import org.openqa.selenium.ElementNotSelectableException; |
|
| 3 | 7 | import org.openqa.selenium.StaleElementReferenceException; |
| 4 | 8 | import org.openqa.selenium.WebDriver; |
| 5 | 9 | import org.openqa.selenium.WebElement; |
| ... | ... | @@ -39,16 +43,24 @@ public class UserManagementPanelPO extends PageArea { |
| 39 | 43 | |
| 40 | 44 | public DataEntryPO findUser(final String username) { |
| 41 | 45 | final CellTablePO<DataEntryPO> table = getUserTable(); |
| 46 | + List<DataEntryPO> dataEntries = new ArrayList<DataEntryPO>(); |
|
| 47 | + waitUntil(() -> { |
|
| 48 | + List<DataEntryPO> entries; |
|
| 49 | + try { |
|
| 50 | + entries = table.getEntries(); |
|
| 51 | + dataEntries.addAll(entries); |
|
| 52 | + } catch (StaleElementReferenceException e) { |
|
| 53 | + entries = null; |
|
| 54 | + } |
|
| 55 | + return entries != null; |
|
| 56 | + }); |
|
| 42 | 57 | for (DataEntryPO entry : table.getEntries()) { |
| 43 | - String name; |
|
| 44 | 58 | try { |
| 45 | - name = entry.getColumnContent("User name"); |
|
| 59 | + if (username.equals(entry.getColumnContent("User name"))) { |
|
| 60 | + return entry; |
|
| 61 | + } |
|
| 46 | 62 | } catch (StaleElementReferenceException e) { |
| 47 | 63 | // entry is not existing any more but must not break iteration |
| 48 | - name = null; |
|
| 49 | - } |
|
| 50 | - if (username.equals(name)) { |
|
| 51 | - return entry; |
|
| 52 | 64 | } |
| 53 | 65 | } |
| 54 | 66 | return null; |
| ... | ... | @@ -56,11 +68,15 @@ public class UserManagementPanelPO extends PageArea { |
| 56 | 68 | |
| 57 | 69 | public EditUserDialogPO getEditUserDialog(final String username) { |
| 58 | 70 | DataEntryPO entry = findUser(username); |
| 59 | - if (entry != null) { |
|
| 60 | - final WebElement action = ActionsHelper.findUpdateAction(entry.getWebElement()); |
|
| 61 | - action.click(); |
|
| 62 | - final WebElement dialog = findElementBySeleniumId(this.driver, "UserEditDialog"); |
|
| 63 | - return new EditUserDialogPO(this.driver, dialog); |
|
| 71 | + try { |
|
| 72 | + if (entry != null) { |
|
| 73 | + final WebElement action = ActionsHelper.findUpdateAction(entry.getWebElement()); |
|
| 74 | + action.click(); |
|
| 75 | + final WebElement dialog = findElementBySeleniumId(this.driver, "UserEditDialog"); |
|
| 76 | + return new EditUserDialogPO(this.driver, dialog); |
|
| 77 | + } |
|
| 78 | + } catch (StaleElementReferenceException e) { |
|
| 79 | + // entry is not existing any more |
|
| 64 | 80 | } |
| 65 | 81 | return null; |
| 66 | 82 | } |
| ... | ... | @@ -87,16 +103,20 @@ public class UserManagementPanelPO extends PageArea { |
| 87 | 103 | } |
| 88 | 104 | |
| 89 | 105 | public void selectUser(String name) { |
| 90 | - final CellTablePO<DataEntryPO> table = getUserTable(); |
|
| 91 | - final DataEntryPO findUser = findUser(name); |
|
| 92 | - if(findUser != null) { |
|
| 93 | - table.selectEntry(findUser); |
|
| 106 | + try { |
|
| 107 | + final DataEntryPO userTableEntry = findUser(name); |
|
| 108 | + if (userTableEntry != null) { |
|
| 109 | + userTableEntry.select(); |
|
| 110 | + } |
|
| 111 | + } catch (StaleElementReferenceException e) { |
|
| 112 | + throw new ElementNotSelectableException("Cannot select user any more. Entry has already been removed from DOM.", e); |
|
| 94 | 113 | } |
| 95 | 114 | } |
| 96 | 115 | |
| 97 | 116 | public void deleteUser(String name) { |
| 98 | 117 | selectUser(name); |
| 99 | 118 | deleteSelectedUser(); |
| 119 | + waitUntilAlertIsPresent(); |
|
| 100 | 120 | driver.switchTo().alert().accept(); |
| 101 | 121 | // wait until cell is removed from page |
| 102 | 122 | waitUntil(() -> findUser(name) == null); |
wiki/info/landscape/olympic-setup.md
| 103 | 123 | index 374f7a7..b5d775a |
| 104 | --- a/wiki/info/landscape/olympic-setup.md |
|
| 124 | +++ b/wiki/info/landscape/olympic-setup.md |
|
| ... | ... | @@ -65,6 +65,6 @@ Three MongoDB nodes are intended to run during regular operations: sap-p1-1:1020 |
| 65 | 65 | |
| 66 | 66 | sap-p1-1 normally is the master for the ``tokyo2020`` replica set. It shall replicate the shared services, in particular ``SecurityServiceImpl``, from ``security-service.sapsailing.com``, like any normal server in our landscape, only that here we have to make sure we can target the default RabbitMQ in eu-west-1 and can see the ``security-service.sapsailing.com`` master directly or even better the load balancer. |
| 67 | 67 | |
| 68 | -*TODO* find out whether an SSH port forward using a DNS hostname will resolve this host name again each time a connection is made. Probably, forwarding to ``security-service.sapsailing.com:443`` could just work... |
|
| 68 | +SSH local port forwards (configured with the ``-L`` option) that use hostnames instead of IP addresses for the remote host specification are resolved each time a new connection is established through this forward. If the DNS entry resolves to multiple IPs or if the DNS entry changes over time, later connection requests through the port forward will honor the new host name's DNS resolution. |
|
| 69 | 69 | |
| 70 | 70 | sap-p1-2 normally is a replica for the ``tokyo2020`` replica set, using the local RabbitMQ running on sap-p1-1. Its outbound ``REPLICATION_CHANNEL`` will be ``tokyo2020-replica`` and uses the RabbitMQ running in ap-northeast-1, using an SSH port forward. A reverse port forward from ap-northeast-1 to the application port 8888 on sap-p1-2 has to be established which replicas running in ap-northeast-1 will use to reach their master through HTTP. This way, adding more replicas on the AWS side in the cloud will not require any additional bandwidth between cloud and on-site network, except that the reverse HTTP channel, which uses only little traffic, will see additional traffic per replica whereas all outbound replication goes to the single exchange in the RabbitMQ node running in ap-northeast-1. |
| ... | ... | \ No newline at end of file |