Skip to content

Commit

Permalink
CLDR-17248 cldr-apps-webdriver misc. updates (#29)
Browse files Browse the repository at this point in the history
-Do not include Admin in pool of simulated users; limit users to ports 5555-5563

-Fix some IntelliJ compiler warnings

-Comments
  • Loading branch information
btangmu authored Dec 14, 2023
1 parent c9f3768 commit 8ecb8e6
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 77 deletions.
2 changes: 1 addition & 1 deletion scripts/selenium-grid-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-4.16.1.jar standalone &

for ((PORT = 5555; PORT <= 5564; PORT++))
for ((PORT = 5555; PORT <= 5563; PORT++))
do
HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-4.16.1.jar standalone --port $PORT &
done
122 changes: 60 additions & 62 deletions src/test/java/org/unicode/cldr/surveydriver/SurveyDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,31 @@

/**
* Perform automated testing of the CLDR Survey Tool using Selenium WebDriver.
*
* <p>
* This test has been used with the cldr-apps-webdriver project running in IntelliJ. At the same time,
* cldr-apps can be running either on localhost or on SmokeTest.
*
* <p>
* This code requires installing an implementation of WebDriver, such as chromedriver for Chrome.
* On macOS, chromedriver can be installed from Terminal with brew as follows:
* brew install chromedriver
* Then, right-click chromedriver, choose Open, and authorize to avoid the macOS error,
* "“chromedriver” cannot be opened because the developer cannot be verified".
* Press Ctrl+C to stop this instance of chromedriver.
*
* <p>
* (Testing with geckodriver for Firefox was unsuccessful, but has not been tried recently.)
*
* Go to https://www.selenium.dev/downloads/ and scroll down to "Selenium Server (Grid)" and
* follow the link to download a file like selenium-server-4.16.1.jar and save it in the parent
* directory of cldr-apps-webdriver.
*
* <p>
* Go to <a href="https://www.selenium.dev/downloads/">selenium.dev/downloads</a> and scroll down
* to "Selenium Server (Grid)" and follow the link to download a file like selenium-server-4.16.1.jar
* and save it in the parent directory of cldr-apps-webdriver.
* <p>
* Add a specific set of simulated test users to the db, consistent with the method getNodeLoginQuery below:
*
* <p>
* mysql cldrdb < cldr-apps-webdriver/scripts/cldr-add-webdrivers.sql
*
* <p>
* Start selenium grid:
*
* <p>
* sh cldr-apps-webdriver/scripts/selenium-grid-start.sh &
*
* <p>
* Open this file (SurveyDriver.java) in IntelliJ, right-click cldr-apps-webdriver in the Project
* panel, and choose "Debug All Tests". You can do this repeatedly to start multiple browsers with
* simulated vetters vetting at the same time.
Expand All @@ -82,18 +82,22 @@ public class SurveyDriver {

/*
* If USE_REMOTE_WEBDRIVER is true, then the driver will be a RemoteWebDriver (a class that implements
* the WebDriver interface). Otherwise the driver could be a ChromeDriver, or FirefoxDriver, EdgeDriver,
* the WebDriver interface). Otherwise, the driver could be a ChromeDriver, or FirefoxDriver, EdgeDriver,
* or SafariDriver (all subclasses of RemoteWebDriver) if we add options for those.
* While much of the code in this class works either way, Selenium Grid needs the driver to be a
* RemoteWebDriver and requires installation of a hub and one or more nodes, which can be done by
*
* sh scripts/selenium-grid-start.sh
*
* It contains commands of these types (first node is default port 5555, second node explicit port 5556):
* It contains commands of these types (where x.x.x stands for the Selenium version number):
*
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-standalone-x.x.x.jar -role hub
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-standalone-x.x.x.jar -role node
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-standalone-x.x.x.jar -role node -port 5556
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-x.x.x.jar standalone
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-x.x.x.jar standalone --port 5555
* HUB_URL=http://localhost:4444/grid/register java -jar selenium-server-x.x.x.jar standalone --port 5556
* ...
*
* The port numbers 5555, ... in selenium-grid-start.sh must be consistent with the method
* SurveyDriver.getNodeLoginQuery.
*/
static final boolean USE_REMOTE_WEBDRIVER = true;
static final String REMOTE_WEBDRIVER_URL = "http://localhost:4444";
Expand Down Expand Up @@ -206,17 +210,12 @@ private void tearDown() {
/**
* Test "fast" voting, that is, voting for several items on a page, and measuring
* the time of response.
*
* <p>
* Purposes:
* (1) study the sequence of events, especially client-server traffic,
* when multiple voting events (maybe by a single user) are being handled;
* (2) simulate simultaneous input from multiple vetters, for integration and
* performance testing under high load.
*
* References:
* https://cldr.unicode.org/index/cldr-engineer/sow "Performance Improvement Goals"
* https://unicode.org/cldr/trac/ticket/11211 "Performance is slow when voting on multiple items on a page"
* https://unicode.org/cldr/trac/ticket/10990 "Fix synchronize (threading)"
*/
private boolean testFastVoting() {
if (!login()) {
Expand All @@ -233,24 +232,24 @@ private boolean testFastVoting() {
String url = BASE_URL + "v#/" + loc + "/" + page;

/*
* Repeat the test for a minute or so.
* Repeat the test a large number of times.
* Eventually we'll have more sophisticated criteria for when to stop.
* This loop to 1000 isn't set in stone.
*/
for (int i = 0; i < 1000; i++) {
final int REPETITION_COUNT = 10000;
for (int i = 0; i < REPETITION_COUNT; i++) {
SurveyDriverLog.println("testFastVoting i = " + i);
try {
if (!testFastVotingInner(page, url)) {
return false;
}
} catch (StaleElementReferenceException e) {
/*
* Sometimes we get "org.openqa.selenium.StaleElementReferenceException:
* Formerly sometimes we got "org.openqa.selenium.StaleElementReferenceException:
* stale element reference: element is not attached to the page document".
* Presumably this happens due to ajax response causing the table to be rebuilt.
* TODO: catch this exception and continue wherever it occurs. Ideally also CldrSurveyVettingTable.js
* may be revised to update the table in place when possible instead of rebuilding the
* table from scratch so often. Reference: https://unicode.org/cldr/trac/ticket/11571
* It may have been due to ajax response causing the table to be rebuilt.
* Survey Tool has since been revised so that the table is rebuilt less often.
* If this exception becomes problematic, we should investigate ways to catch it
* and continue wherever it occurs.
*/
SurveyDriverLog.println("Continuing main loop after StaleElementReferenceException, i = " + i);
}
Expand Down Expand Up @@ -319,7 +318,7 @@ private boolean testFastVotingInner(String page, String url) {
boolean doAdd = (i == rowIds.length - 1) && cell.equals("proposedcell");
String tagName = doAdd ? "button" : "input";
String cellClass = doAdd ? "addcell" : cell;
WebElement rowEl = null, columnEl = null, clickEl = null;
WebElement rowEl = null, columnEl, clickEl = null;
int repeats = 0;
if (verbose) {
String op = cell.equals("nocell") ? "Abstain" : "Vote";
Expand Down Expand Up @@ -521,12 +520,15 @@ public boolean login() {
* Get a query string for logging in as a particular user. It may depend on which Selenium node
* we're running on. It could also depend on BASE_URL if we're running on SmokeTest rather than
* localhost.
*
* Currently this set of users depends on running a mysql script on localhost or SmokeTest.
* <p>
* Currently, this set of users depends on running a mysql script on localhost or SmokeTest.
* See scripts/cldr-add-webdrivers.sql, usage "mysql cldrdb < cldr-apps-webdriver/scripts/cldr-add-webdrivers.sql".
*
* Make sure users have permission to vote in their locales. Admin and TC users can vote in all locales,
* so an easy way is to make them all TC or admin.
* The usernames and passwords here need to agree with that script.
* <p>
* Make sure users have permission to vote in their locales. TC users can vote in all locales,
* so an easy way is to make them all TC.
* <p>
* The range of port numbers 5555, ..., here needs to match selenium-grid-start.sh
*/
private String getNodeLoginQuery() {
if (nodePort == 5555) {
Expand Down Expand Up @@ -556,10 +558,7 @@ private String getNodeLoginQuery() {
if (nodePort == 5563) {
return "[email protected]%20of%20pakistan%20-%20national%20language%20authority.example.com&uid=S5fpuRqHW";
}
/*
* 5564 or other:
*/
return "survey?email=admin@&uid=pTFjaLECN";
throw new RuntimeException("Unexpected node port " + nodePort);
}

/**
Expand Down Expand Up @@ -658,7 +657,7 @@ private boolean testOneLocationAndPage(String loc, String page, String searchStr
WebElement el = null;
try {
el = driver.findElement(By.id("row_44fca52aa81abcb2"));
} catch (Exception e) {}
} catch (Exception ignored) {}
if (el != null) {
SurveyDriverLog.println("✅✅✅ Got it in " + url);
}
Expand Down Expand Up @@ -933,10 +932,10 @@ public boolean waitUntilElementClickable(WebElement el, String url) {
/**
* Wait until the element specified by rowId, cellClass, tagName is clickable.
*
* @param clickEl
* @param rowId
* @param cellClass
* @param tagName
* @param clickEl the element to wait for, if not stale
* @param rowId the id for the row element
* @param cellClass the class of the cell, typically "nocell", "proposedcell", or "addcell"
* @param tagName typically "button" or "input"
* @param url the url we're loading
* @return the (possibly updated) clickEl for success, null for failure
*/
Expand Down Expand Up @@ -996,16 +995,15 @@ public WebElement waitUntilRowCellTagElementClickable(
}

/**
* Click on the element specified by rowId, cellClass, tagName.
* Click on the element specified by clickEl, rowId, cellClass, tagName.
*
* @param clickEl
* @param rowId
* @param cellClass
* @param tagName
* @param clickEl the element to click on, if not stale
* @param rowId the id for the row element
* @param cellClass the class of the cell, typically "nocell", "proposedcell", or "addcell"
* @param tagName typically "button" or "input"
* @param url the url we're loading
* @return true for success, false for failure
*/
public boolean clickOnRowCellTagElement(
public void clickOnRowCellTagElement(
WebElement clickEl,
String rowId,
String cellClass,
Expand All @@ -1016,7 +1014,7 @@ public boolean clickOnRowCellTagElement(
for (;;) {
try {
clickEl.click();
return true;
return;
} catch (StaleElementReferenceException e) {
if (++repeats > 4) {
break;
Expand Down Expand Up @@ -1046,7 +1044,6 @@ public boolean clickOnRowCellTagElement(
SurveyDriverLog.println(
"❗ Test failed in clickOnRowCellTagElement for " + rowId + "," + cellClass + "," + tagName + " in " + url
);
return false;
}

/**
Expand Down Expand Up @@ -1117,13 +1114,14 @@ public Boolean apply(WebDriver webDriver) {
return true;
}

class SurveyDriverTestSession {

String msg = null;
String success = null;
String session = null;
String internalKey = null;
String inactivityTime = null;
static class SurveyDriverTestSession {
String proxyId = null;
/* Additional fields currently unused:
String msg = null;
String success = null;
String session = null;
String internalKey = null;
String inactivityTime = null;
*/
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ public class SurveyDriverData {
* This list of page names was created by temporarily commenting out the toString function
* in PathHeader.java, and inserting this line into the PageId initialization function:
* System.out.println("PageId raw name: " + this.toString());
*
* <p>
* It would be better to have an API for requesting this list from the ST back end at runtime!
*
* <p>
* There is a PageId enum defined in PathHeader.java. We could link with the
* cldr-apps code and access that enum directly. However, there are difficulties
* with initiation, like "java.lang.RuntimeException: CLDRConfigImpl used before SurveyMain.init() called!"
* "Set -DCLDR_ENVIRONMENT=UNITTEST if you are in the test cases." Follow up on that possibility later.
* In the meantime, we can copy and simplify the enum from PathHeader.java, since all we need here
* is an array of strings.
*
* <p>
* PageId versus SectionId: PageId.Alphabetic_Information is in the section SectionId.Core_Data
*
* <p>
* Alphabetic_Information(SectionId.Core_Data, "Alphabetic Information")
*
* <p>
* Each page is one web page; a section may encompass multiple pages, not all visible at once.
* (There may also be multiple headers in one page. See PathHeader.txt which is a source file.)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@ public class SurveyDriverVettingTable {

/**
* Test the vetting table to make sure it contains the expected content under certain circumstances.
*
* Purpose: make sure that code revisions, such as refactoring CldrSurveyVettingTable.js, do not
* cause unintended changes to the table contents.
*
* https://unicode-org.atlassian.net/browse/CLDR-11571 "Avoid rebuilding entire table on Survey Tool update"
* https://unicode-org.atlassian.net/browse/CLDR-11943 "Implement automated testing for Survey Tool table updating"
* <p>
* Purpose: make sure that code revisions do not cause unintended changes to the table contents.
*/
public static boolean testVettingTable(SurveyDriver s) {
if (!s.login()) {
Expand Down Expand Up @@ -146,7 +142,7 @@ public static boolean testVettingTable(SurveyDriver s) {
boolean doAdd = cell.equals("input");
String tagName = doAdd ? "button" : "input";
String cellClass = doAdd ? "addcell" : cell;
WebElement rowEl = null, columnEl = null, clickEl = null;
WebElement rowEl = null, columnEl, clickEl = null;

int repeats = 0;
for (;;) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public SurveyDriverXMLUploader(SurveyDriver s) {

/**
* Test the XMLUploader interface ("Upload XML" in the gear menu).
* Reference: https://unicode-org.atlassian.net/browse/CLDR-13217
*/
public boolean testXMLUploader() {
if (!s.login()) {
Expand Down Expand Up @@ -52,7 +51,7 @@ public boolean testXMLUploader() {

/**
* After new tab or window is created, switch WebDriver to it.
* Otherwise our actions would still operate on the old window.
* Otherwise, our actions would still operate on the old window.
*/
private void switchToNewTabOrWindow() {
WebDriver driver = s.driver;
Expand Down

0 comments on commit 8ecb8e6

Please sign in to comment.