Skip to content

Commit

Permalink
Introduce token management e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzk1 committed Jul 5, 2024
1 parent df8ca3a commit 6a1bccf
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 30 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ jobs:
class: org.apache.streampark.e2e.cases.UserManagementTest
- name: TeamManagementTest
class: org.apache.streampark.e2e.cases.TeamManagementTest
- name: TokenManagementTest
class: org.apache.streampark.e2e.cases.TokenManagementTest
- name: ApplicationsFlink116OnYarnTest
class: org.apache.streampark.e2e.cases.ApplicationsFlink116OnYarnTest
- name: ApplicationsFlink117OnYarnTest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
*/
package org.apache.streampark.e2e.cases;

import org.apache.streampark.e2e.core.StreamPark;
import org.apache.streampark.e2e.pages.LoginPage;
import org.apache.streampark.e2e.pages.system.SystemPage;
import org.apache.streampark.e2e.pages.system.TokenManagementPage;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.shaded.org.awaitility.Awaitility;

import static org.assertj.core.api.Assertions.assertThat;

@StreamPark(composeFiles = "docker/basic/docker-compose.yaml")
public class TokenManagementTest {

private static RemoteWebDriver browser;

private static final String userName = "admin";

private static final String password = "streampark";

private static final String teamName = "default";

private static final String existUserName = "admin";

private static final String newTokenDescription = "test_new_token_description";

@BeforeAll
public static void setup() {
new LoginPage(browser)
.login(userName, password, teamName)
.goToNav(SystemPage.class)
.goToTab(TokenManagementPage.class);
}

@Test
@Order(10)
void testCreateToken() {
final TokenManagementPage tokenManagementPage = new TokenManagementPage(browser);
tokenManagementPage.createToken(existUserName, newTokenDescription);

Awaitility.await()
.untilAsserted(
() -> assertThat(tokenManagementPage.tokenList())
.as("Token list should contain newly-created token")
.extracting(WebElement::getText)
.anyMatch(it -> it.contains(existUserName)));
}

// TODO: use browser clipboard replace local.
// @Test
// @Order(20)
// void testCopyToken() {
// final TokenManagementPage tokenManagementPage = new TokenManagementPage(browser);
// tokenManagementPage.copyToken(existUserName);
//
// new WebDriverWait(browser, Duration.ofSeconds(10));
// String clipboardContent = (String) ((JavascriptExecutor) browser).executeScript("return
// navigator.clipboard.readText();");
//
// System.out.println("Clipboard text: " + clipboardContent);
// Awaitility.await()
// .untilAsserted(
// () ->
// assertThat(tokenManagementPage.tokenList())
// .as("Token list should contain same value")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(clipboardContent)));
// }

@Test
@Order(30)
void testCreateDuplicateToken() {
final TokenManagementPage tokenManagementPage = new TokenManagementPage(browser);
browser.navigate().refresh();
tokenManagementPage.createToken(existUserName, newTokenDescription);

Awaitility.await()
.untilAsserted(
() -> assertThat(tokenManagementPage.errorMessageSearchLayout())
.as("Please select a user").isNotNull());
}

@Test
@Order(40)
void testDeleteToken() {
final TokenManagementPage teamManagementPage = new TokenManagementPage(browser);
browser.navigate().refresh();
teamManagementPage.deleteToken(existUserName);

Awaitility.await()
.untilAsserted(
() -> {
browser.navigate().refresh();
assertThat(teamManagementPage.tokenList())
.noneMatch(it -> it.getText().contains(existUserName));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,65 @@

@Getter
public final class SystemPage extends NavBarPage implements NavBarItem {
@FindBy(
xpath =
"//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'User Management')]//..")
private WebElement menuUserManagement;

@FindBy(xpath = "//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'User Management')]//..")
private WebElement menuUserManagement;
@FindBy(
xpath =
"//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Token Management')]//..")
private WebElement menuTokenManagement;

@FindBy(xpath = "//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Token Management')]//..")
private WebElement menuTokenManagement;
@FindBy(
xpath =
"//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Role Management')]//..")
private WebElement menuRoleManagement;

@FindBy(xpath = "//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Role Management')]//..")
private WebElement menuRoleManagement;
@FindBy(
xpath =
"//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Team Management')]//..")
private WebElement menuTeamManagement;

@FindBy(xpath = "//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Team Management')]//..")
private WebElement menuTeamManagement;
@FindBy(
xpath =
"//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Member Management')]//..")
private WebElement menuMemberManagement;

@FindBy(xpath = "//span[contains(@class, 'streampark-simple-menu-sub-title') and contains(text(), 'Member Management')]//..")
private WebElement menuMemberManagement;
public SystemPage(RemoteWebDriver driver) {
super(driver);
}

public SystemPage(RemoteWebDriver driver) {
super(driver);
public <T extends SystemPage.Tab> T goToTab(Class<T> tab) {
if (tab == UserManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuUserManagement));
menuUserManagement.click();
return tab.cast(new UserManagementPage(driver));
}

public <T extends SystemPage.Tab> T goToTab(Class<T> tab) {
if (tab == UserManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuUserManagement));
menuUserManagement.click();
return tab.cast(new UserManagementPage(driver));
}

if (tab == TeamManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuTeamManagement));
menuTeamManagement.click();
return tab.cast(new TeamManagementPage(driver));
}
if (tab == TeamManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuTeamManagement));
menuTeamManagement.click();
return tab.cast(new TeamManagementPage(driver));
}

if (tab == RoleManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuRoleManagement));
menuRoleManagement.click();
return tab.cast(new RoleManagementPage(driver));
}
if (tab == TokenManagementPage.class) {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(menuTokenManagement));
menuTokenManagement.click();
return tab.cast(new TokenManagementPage(driver));
}

throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}
throw new UnsupportedOperationException("Unknown tab: " + tab.getName());
}

public interface Tab {
}
public interface Tab {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*
*/
package org.apache.streampark.e2e.pages.system;

import org.apache.streampark.e2e.pages.common.NavBarPage;

import lombok.Getter;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;
import java.util.List;

@Getter
public class TokenManagementPage extends NavBarPage implements SystemPage.Tab {

@FindBy(xpath = "//span[contains(., 'Token List')]/..//button[contains(@class, 'ant-btn-primary')]/span[contains(text(), 'Add New')]")
private WebElement buttonCreateToken;

@FindBy(xpath = "//tbody[contains(@class, 'ant-table-tbody')]")
private List<WebElement> tokenList;

@FindBy(xpath = "//button[contains(@class, 'ant-btn')]/span[contains(., 'OK')]")
private WebElement deleteConfirmButton;

@FindBy(className = "ant-form-item-explain-error")
private WebElement errorMessageSearchLayout;

private final CreateTokenForm createTokenForm = new CreateTokenForm();

public TokenManagementPage(RemoteWebDriver driver) {
super(driver);
}

public TokenManagementPage createToken(String existUserName, String description) {
waitForPageLoading();

new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(buttonCreateToken));
buttonCreateToken.click();

new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(createTokenForm.inputUserName()));
createTokenForm.inputUserName().sendKeys(existUserName);
createTokenForm.inputUserName().sendKeys(Keys.RETURN);

createTokenForm.inputDescription().sendKeys(description);
createTokenForm.buttonSubmit().click();
return this;
}

public TokenManagementPage copyToken(String existUserName) {
waitForPageLoading();

tokenList().stream()
.filter(it -> it.getText().contains(existUserName))
.flatMap(
it -> it.findElements(By.xpath("//button[contains(@tooltip,'Copy Token')]")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No Copy button in token list"))
.click();

return this;
}

public TokenManagementPage deleteToken(String existUserName) {
waitForPageLoading();

tokenList().stream()
.filter(it -> it.getText().contains(existUserName))
.flatMap(
it -> it.findElements(By.xpath("//button[contains(@tooltip,'Delete Token')]")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in token list"))
.click();

new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(deleteConfirmButton));
deleteConfirmButton.click();

return this;
}

private void waitForPageLoading() {
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.urlContains("/system/token"));
}

@Getter
public class CreateTokenForm {

CreateTokenForm() {
PageFactory.initElements(driver, this);
}

@FindBy(id = "form_item_userId")
private WebElement inputUserName;

@FindBy(id = "form_item_description")
private WebElement inputDescription;

@FindBy(xpath = "//button[contains(@class, 'ant-btn')]//span[contains(., 'Submit')]")
private WebElement buttonSubmit;

@FindBy(xpath = "//button[contains(@class, 'ant-btn')]//span[contains(., 'Cancel')]")
private WebElement buttonCancel;
}
}

0 comments on commit 6a1bccf

Please sign in to comment.