I am working on a UI. My job is to automate it. I came across the following grid.
When you click on any cell under the Rule column, a browse button appears.
I am supposed to automate this scenario. So, using Firebug I am trying to extract the XPath of that cell.
I used Firebug's inspector to locate that particular cell, so that I can write the XPath for it, but I am unable to locate that cell. Instead, the entire row is getting selected, as shown in next images.
How should I approach this problem?
below code might help you to verify the grid values,
public void verifyTableValues(String expectedValue
) {
try {
//List of Fields values which you want to verify
List<String> expectedValues = Arrays.asList(expectedValue.split("#"));
// you will get the number of rows in Table Select the xpath to /tr
String tableRow = driver.findElements(By.xpath(//table row constant));
int tableRwCnt = getCount(tableRow);
// you will get the number of Columns in Table Select the xpath to /td
String tableColumn = driver.findElements(By.xpath(//table Column constant));
int tableColumnCnt = getCount(tableColumn);
for (int cnt = 1; cnt <= tableRwCnt; cnt++) {
for (int listCount = 1; listCount <= tableColumnCnt; listCount++) {
String actualVal = findElement(By.xpath(tableColumn + "[" + cnt + "]/td["
+ expectedValues.get(listCount) + "]").getText();
String expectdVal = expectedValues.get(listCount);
Assert.assertEquals("Value from table doent Match", expectdVal, actualVal);
}
}
} catch (Exception e) {
// code for exception
}
}
Parameter: expectedValue = test1#test2#test4#test4 (Grid values)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
ERROR: Getting output table show some blank rows in each column after the first column.
This code works as, there is 4 checkboxlist each of it containing 4 list item. When selecting each of the list item it should be displayed in the
specified column .
Right Output: Each column with specified rows in the right position
private void button1_Click(object sender, EventArgs e)
{
Form2 fm = new Form2();
DataTable dt = new DataTable();
dt.TableName = "FoodOrder";
dt.Clear();
dt.Columns.Add("WelcomeDrinks");
dt.Columns.Add("Starter");
dt.Columns.Add("MainMeals");
dt.Columns.Add("Desserts");
for (int i = 0; i < chk1.Items.Count; i++)
{
if (chk1.GetItemChecked(i))
{
DataRow row = dt.NewRow();
row["WelcomeDrinks"] = (string)chk1.Items[i];
dt.Rows.Add(row);
}
}
for (int i = 0; i < chk2.Items.Count; i++)
{
if (chk2.GetItemChecked(i))
{
DataRow workrow = dt.NewRow();
workrow["Starter"] = (string)chk2.Items[i];
dt.Rows.Add(workrow);
}
}
for (int i = 0; i < chk3.Items.Count; i++)
{
if (chk3.GetItemChecked(i))
{
DataRow row = dt.NewRow();
row["MainMeals"] = (string)chk3.Items[i];
dt.Rows.Add(row);
}
}
for (int i = 0; i < chk4.Items.Count; i++)
{
if (chk4.GetItemChecked(i))
{
DataRow row = dt.NewRow();
row["Desserts"] = (string)chk4.Items[i];
dt.Rows.Add(row);
}
}
fm.Grid1.DataSource = dt;
fm.Show();
}
You are neglecting to take into account how many rows you need in the table. Using your current approach where a new row is added for each checked box item in each check box list, then you end up such that only ONE item will be on each row. The first check box items will have their own row and so will each check box list. It may look something like…
Welcome Drinks Starter MainMeal Desserts
Welcome Drinks 1
Welcome Drinks 2
Starter1
Starter3
Main Meal 1
Main Meal 4
Dessert 3
Dessert 4
Is what you need to do is check each CheckedListBox and figure out which check box list has the GREATEST number of items checked. This will tell you how many rows you need in the table. Then, instead of “adding” new rows in the for loops through each list, simply add the item to the existing row using the column name to determine which cell the value goes in.
To get the list check box with the greatest number of “checked” items may look something like…
int maxRows = chk1.CheckedItems.Count;
if (chk2.CheckedItems.Count > maxRows)
maxRows = chk2.CheckedItems.Count;
if (chk3.CheckedItems.Count > maxRows)
maxRows = chk3.CheckedItems.Count;
if (chk4.CheckedItems.Count > maxRows)
maxRows = chk4.CheckedItems.Count;
Then add that number of rows to the table.
for (int i = 0; i < maxRows; i++) {
dt.Rows.Add();
}
Now the table should have the proper number of columns and rows.
Since we know we have to loop through each CheckedListBox to get the “checked” items, it may help if we create a method that takes a string for the column name we want to put the values, the CheckedListBox and the DataTable and returns nothing.
This AddColumnData method, would loop through each of the “checked” items in the given CheckedListBox and add the items to the data table starting on the first row and the given column name. This method may look something like…
private void AddColumnData(string colName, CheckedListBox checkedListBox, DataTable dt) {
int curRowIndex = 0;
DataRow row;
foreach (var checkedItem in checkedListBox.CheckedItems) {
row = dt.Rows[curRowIndex++];
row[colName] = checkedItem;
}
}
With this method, it will make it easier to add the items to the table as shown below…
AddColumnData("WelcomeDrinks", chk1, dt);
AddColumnData("Starter", chk2, dt);
AddColumnData("MainMeals", chk3, dt);
AddColumnData("Desserts", chk4, dt);
I hope this makes sense.
I have following code to create a single pdf with 2 columns and 4 rows. Every cell contains an image.
int labelCount = x;
int columns = 2;
int labelsPerPage = 8;
int rows = labelCount/columns;
int resto = labelCount%columns;
if(resto>0) rows++;
String dest = "path_to_pdf_file";
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
doc.setMargins(0, 0, 0, 0);
Table table = new Table(UnitValue.createPercentArray(columns)).useAllAvailableWidth();
Integer iCount = 0;
for (int i = 1; i <= rows; i++) {
for (int y = 1; y <= columns; y++) {
if(iCount<labelCount) {
String fileName = "name_of_image";
Cell cell = new Cell();
cell.add(new com.itextpdf.layout.element.Image(ImageDataFactory.create("full_path_to_image")).setAutoScale(true));
cell.setBorder(Border.NO_BORDER);
table.addCell(cell);
iCount++;
if(iCount==labelsPerPage-1) {
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
}
}
}
doc.add(table);
doc.close();
If number of labels is bigger than defined limit (8 per page), I want a new page to be created with the following labels.
In my code I used
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
but it generate (I don't know why) a blank page at the beginning. In the second page there are labels.
Which is the right way to add a new page dynamically and put remaining content into it?
Thanks
Essentially in your code you add AreaBreak to the document before you add the table, that's why the blank page is inserted before the table. iText 7 does not allow you to insert page breaks within tables at this point.
To achieve the desired result you need to flush the existing table to the document before moving on to the next page, and create a new table for the next page. Essentially you will be adding a bunch of tables separated with AreaBreak.
The pseudocode which does not require a lot of modifications to your code could look as follows:
Table table = new Table();
for (...) {
// populate table
if ("it's time to insert a page break") {
doc.add(table);
doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
table = new Table(); // create new table
}
}
doc.add(table);
I have stumbled on a very annoying problem when setting column widths on a table in Word (using Microsoft Office 15.0 Object Library, VS 2013). If I run the code below without having any breakpoints, the result becomes incorrect (first column width should be 30%), but if I put a breakpoint (e.g.) on line 47, the generated Word file becomes as I want it to be.
The conclusion I make is that when the debugger stops execution, the given column size values are flushed into the data model and the output will be as I want it to be. Without the breakpoint, the merging of cells changes the widths (e.g. the first column becomes 12,5%).
I have searched for some sort of method/function to make the data model adjust to my programmatically given column sizes before the cell merging, with no luck. Anyone out there that can explain why halting on the breakpoint will change the output?
Regards,
Ola
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Word;
namespace ShowWordProblem
{
class Program
{
private const string WordFileName = #"C:\temp\test.doc";
static void Main(string[] args)
{
var wordApplication = new Application();
wordApplication.Visible = false;
var wordDocument = wordApplication.Documents.Add();
FillDocument(wordDocument);
wordDocument.SaveAs2(WordFileName);
wordDocument.Close();
wordApplication.Quit(Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(wordApplication);
wordApplication = null;
wordApplication = new Microsoft.Office.Interop.Word.Application();
wordApplication.Visible = true;
wordApplication.Documents.Open(WordFileName);
}
private static void FillDocument(Document wordDocument)
{
Range range = wordDocument.Content.Paragraphs.Add().Range;
var table = range.Tables.Add(range, 5, 8);
table.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.PreferredWidth = (float)100.0;
table.Columns.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.Columns.PreferredWidthType = WdPreferredWidthType.wdPreferredWidthPercent;
table.Columns[1].PreferredWidth = 30;
for (int i = 2; i <= 8; i++) table.Columns[i].PreferredWidth = 10;
var widths = table.Columns.OfType<Column>().Select(c => c.Width).ToArray();
MergeGroupHeaderCells(table.Rows[1], 5, 9);
MergeGroupHeaderCells(table.Rows[1], 2, 5);
}
private static void MergeGroupHeaderCells(Row row, int startIndex, int lastIndex)
{
var r = row.Cells[startIndex].Range;
Object cell = WdUnits.wdCell;
Object count = lastIndex - startIndex - 1;
r.MoveEnd(ref cell, ref count);
r.Cells.Merge();
}
}
}
Finally I found a way to force the code to apply the given percentage values to the columns before the merging of the cells, and thereby having the correct widths on all columns.
By adding the following line of code after the last PreferredWidth-assignment:
var info = table.Range.Information[WdInformation.wdWithInTable];
it seems that the given PreferredWidth values are propagated to the columns, and the final rendered word document looks exactly as I want it.
/Ola
I'm trying to paginate items using jQuery Isotope 2.1. I have a set of items which can be filtered. I'd like to be able to limit the displayed items using a range. If I want to display 10 items per page, I'd tell it show all items between 11 and 20 in the filtered set for page 2, for example.
To make matters more complex, items can be sorted as well.
Is there any way to do this?
I thought about toggling a "active" class on the filtered items, then using JS and CSS I would only show items with the "active" class that are within the current range. Not sure if that's the most efficient approach.
Thanks,
Howie
I was able to solve the problem by prototyping the _filter method.
Firstly, I call the _sort method before attempting to filter the items since sorting will affect which items are displayed on each page.
Then I added a few parameters to the options object, such as page and items_per_page. Using these two values, I can calculate the first and last item for the intended page. Even though it's not necessary for pagination, I also added a parameter called activeClass which defaults to active and is added to all matching items. In addition I added and odd-item and an even-item class to each item so that in a list view, for example, I can alternate the row colors.
Lastly, I set a property on the this object called all_matches to the entire set of filtered items. This way I can calculate the total number of pages for my pager. Then I return only the filtered items for the current page.
On the layoutComplete event, I use the page and items_per_page values from the options object in order to calculate the first and last item and update my pager.
I happen to be using Bootstrap along with a customized version of the Bootpag pager which accepts itemsPerPage and totalItems.
You can check out the codepen here. Hope it helps.
Isotope.prototype._filter = function (items)
{
//console.log('FILTER ' + arguments.callee.caller.toString());
var filter = this.options.filter;
filter = filter || '*';
var matches = [];
var all_matches = [];
var hiddenMatched = [];
var visibleUnmatched = [];
var start, end;
//console.log('page: ' + this.options.page + ' items per page: ' +
this.options.items_per_page);
start = (this.options.page - 1) * this.options.items_per_page;
end = this.options.page * this.options.items_per_page;
//console.log('start: ' + start + ' end: ' + end + ' page: ' +
this.options.page);
// we want to set the current value of filteredItems to all items
before we sort
// we must sort first becuase we need to make sure we are showing
// the correct results for each page in the correct order
this.filteredItems = items;
this._sort();
if (this.options.activeClass === undefined ||this.options.activeClass === '')
{
this.options.activeClass = 'active';
}
var test = this._getFilterTest(filter);
// test each item
for (var i = 0, len = items.length; i < len; i++)
{
//console.log('item: ' + i, $(items[i].element).find('.grid-item-title .asset-link').text(), items[i]);
var item = items[i];
if (item.isIgnored)
{
continue;
}
// add item to either matched or unmatched group
var isMatched = test(item);
// add to matches if its a match
if (isMatched)
{
all_matches.push(item);
// before we add it to the matched set, let's make sure if falls within range
// it needs to be part of the current page set otherwise we filter it out
if (all_matches.length > start && all_matches.length <= end)
{
matches.push(item);
var odd_even = (matches.length % 2 === 0) ? 'even-item' : 'odd-item';
$(item.element).addClass(this.options.activeClass + ' ' + odd_even);
} else
{
// we need to reset isMatched if we're not using it on the current page
isMatched = false;
$(item.element).removeClass(this.options.activeClass + ' odd-item even-item');
}
}
// add to additional group if item needs to be hidden or revealed
if (isMatched && item.isHidden)
{
// reveal these items
hiddenMatched.push(item);
} else if (!isMatched && !item.isHidden)
{
// hide these items
visibleUnmatched.push(item);
}
}
var _this = this;
function hideReveal()
{
_this.reveal(hiddenMatched);
_this.hide(visibleUnmatched);
}
if (this._isInstant)
{
this._noTransition(hideReveal);
} else {
hideReveal();
}
// set all matches as a property on 'this' since we'll need it later to build the pager
this.all_matches = all_matches;
return matches;
};
H
In JavaFX, how to get the cell renderer instance for a given cell of a given TableColumn?
In Swing, the way to do it would be to invoke getTableCellRendererComponent() on the TableCellRenderer for that column and pass it the row and column indices. But JavaFX seems to be very different. I tried searching and going through the TableColumn API but I don't seem to be able to figure this out. Maybe I have to do something with getCellFactory().
My goal is to query the preferred width for each cell renderer of a column and then calculate the width to set on the column so that the contents of all the cells of that column are fully visible.
A question was asked here - JavaFX 2 Automatic Column Width - where the goal of the original poster was the same as that of mine. But there hasn't been a satisfactory answer there yet.
There is resizeToFit() method in TableColumnHeader class. Unfortunately it is protected. How about just copy-paste the code to your application and change it a bit:
protected void resizeToFit(TableColumn col, int maxRows) {
List<?> items = tblView.getItems();
if (items == null || items.isEmpty()) return;
Callback cellFactory = col.getCellFactory();
if (cellFactory == null) return;
TableCell cell = (TableCell) cellFactory.call(col);
if (cell == null) return;
// set this property to tell the TableCell we want to know its actual
// preferred width, not the width of the associated TableColumn
cell.getProperties().put("deferToParentPrefWidth", Boolean.TRUE);//the change is here, only the first parameter, since the original constant is not accessible outside package
// determine cell padding
double padding = 10;
Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
if (n instanceof Region) {
Region r = (Region) n;
padding = r.getInsets().getLeft() + r.getInsets().getRight();
}
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
double maxWidth = 0;
for (int row = 0; row < rows; row++) {
cell.updateTableColumn(col);
cell.updateTableView(tblView);
cell.updateIndex(row);
if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
getChildren().add(cell);
cell.impl_processCSS(false);
maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
getChildren().remove(cell);
}
}
col.impl_setWidth(maxWidth + padding);
}
Then you can call the method after load data:
for (TableColumn clm : tblView.getColumns()) {
resizeToFit(clm, -1);
}