Read the DOM in Watin

3.3k Views Asked by At

I'm working on watin script which read forms on e-shop. In this test I must read price of some items, but always I got information from the first item on the page. I know the KEYWORD, and should read values from "usd" and "eur".

Please help.

Example of table

<table class="item available">
<tbody>
    <tr>
        <td class="img-block skyblue-links">
        <td class="detail">
            <div class="title">
                <a href="http://...">KEYWORD</a>
            </div>
            <p>
            <table>
            <tbody>
                <tr>
                    <td class="price-status">
                        <div class="status">
                        <div class="price">
                            <div class="eur">
                            17096
                            <span>
                            </div>
                            <div class="usd">$ 2 129</div>
                        </div>
                    <div class="to-buy-link" name="buy_catalog">
                    </td>
                    <td class="rating-performance">
                </tr>
            </tbody>
            </table>
        </td>
    </tr>
</tbody>

1

There are 1 best solutions below

2
On BEST ANSWER

Here is a quick and dirty example

        using (var browser = new IE(new Uri(HtmlTestBaseURI, "Test.htm")))
        {
            var details = browser.TableCells.Filter(Find.ByClass("detail"));
            var item = details.First( cell => cell.Link(Find.ByText("KEYWORD")).Exists);
            if (!item.Exists) return;
            var euro = item.Div(Find.ByClass("eur")).Text;
            var dollar = item.Div(Find.ByClass("usd")).Text;
        }

Basic steps:

  • Find All TableCells having a class detail
  • Find the First tablecell in this collection that has a link with the text "KEYWORD"
  • If none found, exit
  • else read the relevant divs inside the tablecell

If I have time I'll convert this example into a Control. Could you post example HTML for two items?

update 4 feb 2011:

Previous example had a lot of knowledge of the html dom structure, the following code does abstract this knowledge into a reusable control. This provides one single point of truth regarding the dom structure of an item, makes it reusable and keeps your (test) code clean.

The Item control's scope is the table with the item information. I needed an example with 2 items to figure this out. These item tables are "recognized" by the fact they have a class name containing "item". All element lookups inside the control are done within the scope of the matching table.

    [Test]
    public void Should_be_better_readable_when_modeled_as_control()
    {
        using (var browser = new IE(new Uri(HtmlTestBaseURI, "Test.htm")))
        {
            var item = browser.Control<Item>(itm => itm.Title == "KEYWORD");
            // OR
            // var item = browser.Controls<Item>().First(itm => itm.Title == "KEYWORD");
            if (!item.Exists) return;
            var euro = item.GetPriceFor("eur");
            var dollar = item.GetPriceFor("usd");
        }
    }

    public class Item : Control<Table>
    {
        public override Constraints.Constraint ElementConstraint
        {
            get { return Find.ByClass(clss => clss != null && clss.Contains("item")); }
        }

        public string Title
        {
            get { return Element.Div(Find.ByClass("title")).Text.Trim(); }
        }

        public string Url
        {
            get { return Element.Div(Find.ByClass("title")).Link(Find.First()).Url; }
        }

        public string GetPriceFor(string currency)
        {
            return Element.Div(Find.ByClass("price")).Div(Find.ByClass(currency)).Text;
        }
    }

HTH, Jeroen