I have 20 or more tables. Number of tables could be different. To determine number of tables I use driver.findElements(By.xpath(...)).size() functionality.
For one table I created DataProvider method, that returns an object:
@DataProvider
public Object[][] tableValues() throws Exception {
.........
int c = 0; // here I use HashMap<String, String> object
//filled with entry.getValue = column label, entry.getKey() = cell value of column
Object obj[][] = new Object[tableMap.size()][4];
print("========== DataProvider object generating...");
print("========== Size of tableMap: "+tableMap.size());
for (Map.Entry entry: tableMap.entrySet()) {
obj[c][0] = fileName;
obj[c][1] = entry.getValue();
obj[c][2] = entry.getKey();
obj[c][3] = false;
c++;
}
obj[tableMap.size()-1][3]=true;
return obj;
}
In this case I have a fileName = "file name 1" for the first table.
I use this object to assert that every value of table could be found in database through web search functionality. For the search I use only entry.getKey value, but use fileName and entry.getValue in extent reports to show where the value is located.
I hardcoded fileName here, checking values only for table with this fileName.
I want to repeat both DataProvider and Test method "number of tables" times, using for each time the next table number starting from 01. I could say it in different way: For example, I've got 20 tables. I should use 20 DataProviders with 20 different fileNames and I should run @Test(dataProvider = "tableValues") 20 times also with different table names. I could not get 20 table sets in one big DataProvider. I could do it, but I should not do it, because of tables' values could change after 10-20 minutes and it could change test results. I get restricted number of rows and quickly check them. Then I go to another table fetching values, asserting values and so on.
@Test(dataProvider = "tableValues")
public void ValuesAsserting(String fileName, String columnName, String cellValue, boolean flag) throws Exception {
if (cellValue != null) { //Steps:
inputField(cellValue, "searchFieldXpath"); //1
buttonClick("searchButtonXpath"); //2
waitLoaderDisplayed(); //3
waitLoaderHidden(); //4
print("Verifying "+fileName+": "+columnName+": "+cellValue);
logger = extent.createTest("Verifying of "+fileName+" value: "+"\n"+columnName+": "+cellValue);
assertValueIsInResults(cellValue,"searchResultsXpath"); //5
// asserts file's generation time before and after testing
scanTimeAssert(flag); //After tests
}
}
I've found a solution in TestNG documentation. @Factory annotation helps to resolve it.
// It is my main class Factory provides with file's number required for xpath to open it and go further:
public class AllTablesTest extends BaseTest {
// It is the main thing I added to get it worked within factory:
private int fNumber;
public AllTablesTest(int fileNumber) {
this.fNumber = fileNumber;
}
........
}
// WebTestFactory class I get from TestNG documentation and changed it to get desirable number of files:
public class WebTestFactory extends BaseTest{
int numberOfFiles;
@Factory
public Object[] createInstances() throws Exception {
getDriver("Chrome");
getUrl("adminUrl");
login(getValue("adminEmail"),getValue("adminPass"));
numberOfFiles = getNumberOfFiles();
Object[] result = new Object[numberOfFiles];
for (int i=0; i<numberOfFiles; i++) {
result[i]=new AllTablesTest(i+1);
}
return result;
}