re-enabled TestLinkCreation based on a Route53 CNAME pointing to 127.0.0.1

This commit is contained in:
Axel Uhl
2025-05-22 15:06:54 +02:00
parent d5bb6e5738
commit 0d30d4527f
2 changed files with 49 additions and 22 deletions
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.gwt.home.desktop.places.qrcode.QRCodePlace.InvitationMode;
import com.sap.sailing.gwt.ui.shared.MarkDTO;
import com.sap.sailing.gwt.ui.shared.QRCodeEvent;
import com.sap.sailing.landscape.common.SharedLandscapeConstants;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Triple;
@@ -57,7 +58,7 @@ public class QRCodePresenter {
private boolean isSecureServer(Triple<String, String, Integer> correctServerHost) {
String host = correctServerHost.getB();
if (host.endsWith("sapsailing.com")) {
if (host.endsWith(SharedLandscapeConstants.DEFAULT_DOMAIN_NAME)) {
return true;
}
if (host.equals("127.0.0.1")) {
@@ -1,5 +1,6 @@
package com.sap.sailing.selenium.test.adminconsole;
import java.net.SocketException;
import java.net.URL;
import java.util.Date;
@@ -11,7 +12,6 @@ import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
@@ -46,7 +46,7 @@ import com.sap.sailing.selenium.test.adminconsole.smartphonetracking.RegisterCom
* There are various link creation logic in AdminConsole. This test is to cover them.
* <p>
*
* TODO The reply from branch.io regarding the test failures was this:
* The reply from branch.io regarding the test failures in connection with "localhost" addresses was this:
* <p>
*
* "It looks like the engineering team confirmed there was an update to security and this behavior is expected. Branch
@@ -54,9 +54,12 @@ import com.sap.sailing.selenium.test.adminconsole.smartphonetracking.RegisterCom
* known risks/issues/phishing for security reasons. Since WAF does not have access to the link data, the error does not
* raise when localhost is set an encapsulated link data.<p>
*
* It's recommend that clients use a hosted pre-prod environment for their internal testing, rather than localhost"
* It's recommend that clients use a hosted pre-prod environment for their internal testing, rather than localhost"<p>
*
* Therefore, we've installed a DNS CNAME alias for the test-qr-code-place.sapsailing.com domain name to point to
* 127.0.0.1. This domain name is used in the test to replace localhost in the URLs and is accepted in URL parameters
* by branch.io.
*/
@Ignore("Until branch.io has resolved their CloudFront issue delivering an error 403 for our test links")
public class TestLinkCreation extends AbstractSeleniumTest {
private static final Logger LOG = LoggerFactory.getLogger(TestLinkCreation.class);
@@ -116,7 +119,7 @@ public class TestLinkCreation extends AbstractSeleniumTest {
* an additional confirmation on production server.
*/
@Test
public void testRegattaOverviewInvitationLinkCreation() {
public void testRegattaOverviewInvitationLinkCreation() throws SocketException {
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
// create an event and regatta
EventConfigurationPanelPO events = adminConsole.goToEvents();
@@ -141,12 +144,16 @@ public class TestLinkCreation extends AbstractSeleniumTest {
Assert.assertTrue(createdInvitationUrl.contains("secret=" + secret));
Assert.assertTrue(createdInvitationUrl.contains("event_id=" + selectedEventId));
Assert.assertTrue(createdInvitationUrl.contains("server=http%3A%2F%2Flocalhost%3A"));
// "localhost" is not accepted by branch.io, so we need to replace by some artificial server;
// that server will not have to be resolved during the test, so it can be a random string
final String localNonLoopbackAddress = getNonLoopbackLocalhostAddress();
final String nonLocalhostCreatedInvitationUrl = createdInvitationUrl.replace("localhost", localNonLoopbackAddress);
registrationLinkWithQRCode.clickOkButtonOrThrow();
HomePage.goToHomeUrl(getWebDriver(), createdInvitationUrl);
HomePage.goToHomeUrl(getWebDriver(), nonLocalhostCreatedInvitationUrl);
Wait<WebDriver> wait = new WebDriverWait(getWebDriver(), 30);
// confirm dialog on my.sapsailing.com to redirect back to localhost
wait.until(ExpectedConditions.numberOfElementsToBe(
By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
// Confirm dialog will be shown on sapsailing.com to redirect back to localhost or non-default domain
// wait.until(ExpectedConditions.numberOfElementsToBe(
// By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
// here we are back on localhost (Home.html#QRCodePlace)
wait.until(ExpectedConditions.presenceOfElementLocated(
By.xpath("//div[contains(text(), '" + EXPECTED_PUPLIC_INVITE_QR_CODE_TITLE + "')]")));
@@ -154,14 +161,24 @@ public class TestLinkCreation extends AbstractSeleniumTest {
.presenceOfElementLocated(By.xpath("//a[contains(text(), '" + EXPECTED_QR_LINK_TEXT + "')]")));
Assert.assertTrue(qrCodeLink.getAttribute("href").startsWith(INVITATION_QR_CODE_BASE));
Assert.assertTrue(qrCodeLink.getAttribute("href").contains("secret=" + secret));
Assert.assertTrue(qrCodeLink.getAttribute("href").contains("server=http%3A%2F%2Flocalhost%3A"));
Assert.assertTrue(qrCodeLink.getAttribute("href").contains("server=http%3A%2F%2F"+localNonLoopbackAddress+"%3A"));
}
/**
* @return an alias hostname for localhost; branch.io does not accept localhost nor 127.0.0.1 nor any
* local IP address such as 192.168.x.x or 10.x.x.x. The way we solve this here is to establish a Route53
* CNAME alias DNS record for the test-qr-code-place.sapsailing.com domain name to point to 127.0.0.1.
* branch.io is not smart enough to check the DNS record and will accept this domain name.
*/
private String getNonLoopbackLocalhostAddress() throws SocketException {
return "test-qr-code-place.sapsailing.com";
}
/**
* Testing the generation of an invitation QR code for the Race Manager App.
*/
@Test
public void testRaceManagerAppInvitationLink() {
public void testRaceManagerAppInvitationLink() throws SocketException {
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
RaceManagementAppPanelPO raceManagerApp = adminConsole.goToRaceManagerApp();
DeviceConfigurationCreateDialogPO createDeviceConfiguration = raceManagerApp.createDeviceConfiguration();
@@ -172,24 +189,29 @@ public class TestLinkCreation extends AbstractSeleniumTest {
Matcher<String> matcher = Matchers.matchesRegex(CHECK_RACE_APP_URL_REGEX);
String createdInvitationUrl = qrCodeDialog.getUrl();
MatcherAssert.assertThat("Check URL", matcher.matches(createdInvitationUrl));
HomePage.goToHomeUrl(getWebDriver(), createdInvitationUrl);
// confirm dialog on my.sapsailing.com to redirect back to localhost
// "localhost" is not accepted by branch.io, so we need to replace by some artificial server;
// that server will not have to be resolved during the test, so it can be a random string
final String localNonLoopbackAddress = getNonLoopbackLocalhostAddress();
final String nonLocalhostCreatedInvitationUrl = createdInvitationUrl.replace("localhost", localNonLoopbackAddress);
HomePage.goToHomeUrl(getWebDriver(), nonLocalhostCreatedInvitationUrl);
Wait<WebDriver> wait = new WebDriverWait(getWebDriver(), 30);
wait.until(ExpectedConditions.numberOfElementsToBe(
By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
// Confirm dialog will be shown on sapsailing.com to redirect back to localhost or non-default domain
// wait.until(ExpectedConditions.numberOfElementsToBe(
// By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
// here we are back on localhost (Home.html#QRCodePlace)
wait.until(ExpectedConditions.presenceOfElementLocated(
By.xpath("//div[contains(text(), '" + EXPECTED_RACE_MANAGER_APP_QR_CODE_TITLE + "')]")));
WebElement qrCodeLink = wait.until(ExpectedConditions
.presenceOfElementLocated(By.xpath("//a[contains(text(), '" + EXPECTED_QR_LINK_TEXT + "')]")));
MatcherAssert.assertThat("Check URL", matcher.matches(qrCodeLink.getAttribute("href")));
Matcher<String> matcherWithNonLocalhostAddress = Matchers.matchesRegex(CHECK_RACE_APP_URL_REGEX.replace("localhost", getNonLoopbackLocalhostAddress()));
MatcherAssert.assertThat("Check URL", matcherWithNonLocalhostAddress.matches(qrCodeLink.getAttribute("href")));
}
/**
* Device registration via QR code test.
*/
@Test
public void testDeviceRegistation() throws InterruptedException {
public void testDeviceRegistation() throws InterruptedException, SocketException {
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
// create an event and regatta
EventConfigurationPanelPO events = adminConsole.goToEvents();
@@ -229,11 +251,15 @@ public class TestLinkCreation extends AbstractSeleniumTest {
Matcher<String> competitorMatcher = Matchers.matchesRegex(competitorUrlPattern);
String qrCodeUrl = addDeviceMappingsDialog.getQrCodeUrl(competitorUrlPattern);
MatcherAssert.assertThat("Check URL", competitorMatcher.matches(qrCodeUrl));
// "localhost" is not accepted by branch.io, so we need to replace by some artificial server;
// that server will not have to be resolved during the test, so it can be a random string
final String localNonLoopbackAddress = getNonLoopbackLocalhostAddress();
final String nonLocalhostQRCodeUrl = qrCodeUrl.replace("localhost", localNonLoopbackAddress);
// check redirect
getWebDriver().get(qrCodeUrl);
// confirm dialog on my.sapsailing.com to redirect back to localhost
wait.until(ExpectedConditions.numberOfElementsToBe(
By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
getWebDriver().get(nonLocalhostQRCodeUrl);
// Confirm dialog will be shown on sapsailing.com to redirect back to localhost or non-default domain
// wait.until(ExpectedConditions.numberOfElementsToBe(
// By.xpath("//button[contains(text(), 'Yes')] | //button[contains(text(), 'Ja')]"), 1)).get(0).click();
// here we are back on localhost (Home.html#QRCodePlace)
wait.until(ExpectedConditions.presenceOfElementLocated(
By.xpath("//div[contains(text(), '" + EXPECTED_DEVICE_REGISTRATION_QR_CODE_TITLE + "')]")));