This is a migrated thread and some comments may be shown as answers.

Automate click in cell in Kendo Grid htmlhelper

18 Answers 228 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Tabatha
Top achievements
Rank 1
Tabatha asked on 12 Apr 2017, 08:31 PM

I have an MVC application in which a view contains a Kendo Grid htmlhelper.  As such, I just specify the columns in the grid, and when the view is loaded it adds the rows and data based on the data source:

@(Html.Kendo().Grid<CustomerJob>()
                            .Name("customerJobGrid")
                            .DataSource(dataSource => dataSource
                                .Ajax()
                                .Sort(sort =>
                                {
                                    sort.Add("IsFavorite").Descending();
                                    sort.Add("JobNo").Descending();
                                })
                                .Read(read => read.Action("Jobs_Active_Read", "DashBoard"))
                                .Model(model => model.Id(p => p.JobNo)
                                )
                            )
                            .Columns(columns =>
                            {
                                columns.Template(p => { }).ClientTemplate(
                            "# if(IsFavorite == 1) { #" +
                                "<span id=\"star-#=NavCustomerNo#-#=JobNo#\" class=\"favorite-star glyphicon glyphicon-star\"></span>" +
                             "# } else { #" +
                                "<span id=\"star-#=NavCustomerNo#-#=JobNo#\" class=\"favorite-star glyphicon glyphicon-star-empty\"></span>" +
                             "# } # "
                            ).Width(50);
                                columns.Bound(p => p.CustomerName).Title("Account");
                                columns.Bound(p => p.Nickname).Title("Name");
                                columns.Bound(p => p.JobNo).Title("Job ID").Width(90).MinScreenWidth(768);
                            })
                            .Pageable()
                            .Sortable()
                            .Scrollable()
                            .Filterable()
                            .Mobile(MobileMode.Disabled)
                            .Selectable(selectable => selectable
                                         .Mode(GridSelectionMode.Single)
                                         .Type(GridSelectionType.Row))
                                        .Events(events => events.Change("onChange"))
                            .HtmlAttributes(new { style = "height:400px;" })
                )

So in the view, I can click within a cell in the grid and it will take me to a page specific for that row.

I would like to automate this using the test framework, so my test can find a cell either by a specified row and column or by a specified text content, and then click in that cell.

I did find this thread, but it's specific to an actual Kendo UI Grid:  http://www.telerik.com/forums/automating-kendo-ui-controls

I need help with this for the htmlhelper version.

Thank you!

18 Answers, 1 is accepted

Sort by
0
Elena
Telerik team
answered on 13 Apr 2017, 02:07 PM
Hello Tabatha,

Thank you for choosing Telerik Testing Framework. 

Please find the following sample code article which could be useful to you. You will need to adjust the code to your exact scenario and application specifics though you could use it as reference. 

Let me know if further assistance is required. Thank you! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 18 Apr 2017, 02:26 PM

Thank you for the reference, Elena!  That was quite helpful.  This is what I put together to automate clicking in the 2nd cell of the first row:

        Dim job As HtmlTableCell
        Dim activeJobs As HtmlTable = myManager.ActiveBrowser.Find.ByExpression(Of HtmlTable)("id=customerJobGrid", "|", "tagIndex=table:1")
        For Each row As HtmlTableRow In activeJobs.AllRows
            For Each cell As HtmlTableCell In row.Cells
                If row.RowIndex = 0 AndAlso cell.CellIndex = 1 Then
                    job = cell
                    Exit For
                End If
            Next
        Next
        Return job

 

As it is, it does find the table, which is great.  But for some reason it says the cell count for 'row' is only 1, when it should be 6.  In fact, 'row' is identified as a td with colspan = 6.  As such, job is returned as nothing because it only goes through the loop once.  Why is cell count only 1?

 

0
Tabatha
Top achievements
Rank 1
answered on 20 Apr 2017, 07:05 PM

I really need an answer to this - our site that I'm trying to create automated tests for uses html kendo grids rather extensively, so I'm kind of stuck until I have one working.  I did just like in the example that was linked - why is row.Cells count coming up as only 1 and not 6?

 

0
Elena
Telerik team
answered on 21 Apr 2017, 11:34 AM
Hi Tabatha,

Thanks for getting back to me with further details. 

However in order to understand the reason for that behavior I would need a sample page which reproduces the issue to test againsst or even better access to the particular application under test. Would it be possible to provide me an example of such control? 

I hope to hear from you soon! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 21 Apr 2017, 01:40 PM
With all due respect, I can not give you access to my actual application under test, and I did give you a sample - I provided the code for the grid being tested and the code for my test in finding a cell in that grid.  If you already have a site you can get to that also uses an html kendo grid, then just create a new console project that references ArtOfTest.WebAii (or maybe you even already have one of those too), and add that code I provided for finding the cell, modifying the find expression accordingly.  If it works for you but not for me then we can try to see what's different.  FYI, I'm using ArtOfTest version 4.0.30319 (2017.1.207.0).  Thank you!
0
Elena
Telerik team
answered on 26 Apr 2017, 10:29 AM
Hi Tabatha,

Thanks for getting back to me. 

The reason I requested a sample page to test against is because of the different structure a Kendo grid might have. I couldn't build the initially provided example since I do not have the source distributed in columns. 

However I tested the code you provided against a sample Telerik page and here you could find attached the script. It contains some comments as well as multiple print to log actions to visualize what is found and to be able to easier verify how to locate the required elements. 

I hope this will be helpful to you. 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 26 Apr 2017, 03:00 PM

HI, Elena -

Thank you for the sample.  I tried it myself, like so:

        mySettings.Web.DefaultBrowser = BrowserType.FireFox
        myManager.Start()
        myManager.LaunchNewBrowser()
        myManager.ActiveBrowser.NavigateTo("http://demos.telerik.com/aspnet-mvc/grid/index")
        Try
            myManager.ActiveBrowser.WaitForUrl("http://demos.telerik.com/aspnet-mvc/grid/index", False, 3000)
        Catch toe As TimeoutException
            Console.WriteLine("Failed to get to page")
        Catch ex As Exception
            Console.WriteLine("Something other than a timeout")
        End Try

        Dim job As HtmlTableCell
        Dim activeJobs As HtmlTable = myManager.ActiveBrowser.Find.ByExpression(Of HtmlTable)("id=grid", "|", "tagIndex=table:1")
        Assert.IsNotNull(activeJobs)

        Dim tdCells = activeJobs.Find.AllByTagName("td")
        'print the number of td elements found
        Console.WriteLine("Number of td cells: " & tdCells.Count.ToString())

 

This comes up with 80 cells!  I don't understand why this is working here, but not for the grid on our site that I'm trying to test (where it finds an htmltable, but number of td cells is only 1).

I tried comparing the html structure between the two using F12 - they look the same (a div with an id, then a couple of nestled divs where the first table is which is just the column headings, then a couple other nestled divs where the 2nd table is containing the actual data, hence the find expression being what it is.  And in my grid it shows 6 td's where yours shows 4 td's.).

So in comparing the code used in generating the two grids, what seems to be the biggest difference (and hence so far the only thing I can figure might have something to do with it) is the data source.

-  It looks like (correctly me if I'm wrong) the data source for the grid on your page is a view model where the bound columns map to properties of the view model which are collected in a select directly in the grid's read function in the controller.

-  Ours, however, comes from a SQL view.  The grid's read function in the controller actually calls a Function within our SQL DB, which gathers the data via a complex query.

Could that actually be the cause?  I wouldn't have thought, being that the html does come up with the expected td's as described above.  But if it is, why...and what can be done to get around it?

Thank you!

0
Elena
Telerik team
answered on 01 May 2017, 08:22 AM
Hello Tabatha,

Thanks for your cooperation. 

The reason I asked for the exact table you are automating was exactly that it might be different and specific to what is present and parsed as content. Without an example it would be quite hard to determine what the reason for that behavior could be. 

As visible in the provided example the functions you are trying to use are working fine. However there are probably some specifics in the application under test which prevents the expected results. I would kindly ask if it would be possible to provide a sample public accessible grid preforming the same behavior as the one you automate so that I could test against it. 

Thanks in advance for your understanding! I hope to hear from you soon! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 03 May 2017, 08:14 PM

HI, Elena -

I am honestly trying to figure out how best I can provide you with what you're asking.  Following is the code from the application under test as to how the data is populated in the grid....maybe you all can take a look at that in the meantime at least if that'll help:

In the Controller:

        public ActionResult Jobs_Active_Read([DataSourceRequest] DataSourceRequest request, string JobSearchText) {

            try {
                var db = new OurContext();
                IQueryable<TfCustomerJobListReturnModel> jobs = db.TfCustomerJobList(CurrentUser.UserId, false);
                var result = jobs.ToDataSourceResult(request);

                var jsonText = JsonConvert.SerializeObject(result, Formatting.None, new JsonSerializerSettings {
                    PreserveReferencesHandling = PreserveReferencesHandling.Objects
                });
                return Content(jsonText, "application/json");

            } catch (Exception ex) {
                logger.Error("Jobs_Active_Read", ex);
                return null;
            }
        }

This is the TfCustomerJobList function in our SQL DB:

    CREATE FUNCTION [dbo].[tf_CustomerJobList]
        (    
            @UserId int,
            @ActiveFlag bit
        )
        RETURNS TABLE
        AS
        RETURN
        (
            SELECT DISTINCT
                         SH.[Bill-to Customer No_] AS NavCustomerNo,
                         J.No_ AS JobNo,
                         C.Name AS CustomerName,
                         J.Description,
                         J.[Site Address] AS SiteAddress,
                         J.[Site City] AS SiteCity,
                         J.[Site State] AS SiteState,
                         J.[Site Zip] AS SiteZip,
                         case when UC.UserId is not null then 1 else 0 end as OwnerFlag,
                         isnull(JP.IsFavorite,0) as IsFavorite,
                         isnull(JP.IsInactive,0) as IsInactive,
                         case when jp.Nickname collate SQL_Latin1_General_CP1_CI_AS is null then J.Description collate SQL_Latin1_General_CP1_CI_AS  else jp.Nickname collate SQL_Latin1_General_CP1_CI_AS end  Nickname
        FROM            
        [oursqlserver].dbo.Job AS J
            INNER JOIN  [oursqlserver].dbo.[Inc$Sales Header] AS SH
                ON J.No_ = SH.[Job No_]
            INNER JOIN [oursqlserver].dbo.Customer AS C
                ON SH.[Bill-to Customer No_] = C.No_
            left join UserNavCustomer UC
                on SH.[Bill-to Customer No_] collate SQL_Latin1_General_CP1_CI_AS = UC.[NavCustomerNo] collate SQL_Latin1_General_CP1_CI_AS and  UC.UserId = @UserId
            left join [dbo].[InvitedGuestJob] GJ
                on SH.[Bill-to Customer No_] collate SQL_Latin1_General_CP1_CI_AS = GJ.[NavCustomerNo] collate SQL_Latin1_General_CP1_CI_AS
                and GJ.GuestUserId = @UserId and GJ.JobNo collate SQL_Latin1_General_CP1_CI_AS = J.No_ collate SQL_Latin1_General_CP1_CI_AS
                and GJ.InvitationExpiration >= GETDATE()
            left join (select * from [dbo].[UserNavJobProfile] where UserId = @UserId) JP
                on JP.NavJobNo collate SQL_Latin1_General_CP1_CI_AS = J.No_ collate SQL_Latin1_General_CP1_CI_AS
                
        WHERE  (SH.Suspended = 0)
        AND
        (SH.[Document Type] = 1)
        and
        (UC.UserId is not null or GJ.GuestUserId is not null)
        and
        isnull(JP.IsInactive,0)  = @ActiveFlag
    )

 

So where in your Controller, the read method returns the results of a select that is a simple straight property - to - column mapping....Ours returns the contents of a JsonText object.  So I can't help but figure that maybe for some reason, even though this does work in rendering the grids, behind it the test framework only sees this as one big 'thing' (i.e. 1 td)??

Do you guys have at least a place you can publish stuff to try out?  If so, I could try to at least provide you with an actual complete project that models this one with the code I pasted....?

Thank you!

0
Elena
Telerik team
answered on 08 May 2017, 10:05 AM
Hi Tabatha,

Thanks for providing additional details. Could you please allow me some time to try to build a sample as per the provided code? Once I get my observations I will get back to you. 

Thanks! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Elena
Telerik team
answered on 09 May 2017, 08:47 AM
Hi Tabatha,

Thanks for allowing me some time. 

I reviewed the provided code sample however without having the exact controls you use, the data and etc. the chance to replicate the exact same grid and behavior is not very high. Since the sample script I provided you works against the demo site it seems the issue is related to the exact grid in your application. 

Since the application under test could not be accessed outside of your network I would like to share our next best option. Could you please capture a Fiddler trace of the problem page and grid. We have about a 75% success rate using a Fiddler trace to simulate your web server and reproduce problems. 

To record a Fiddler trace please follow the below steps steps:

1 Start Fiddler - note no browser should be open
2 Click Clear Cache
3 If your site uses HTTPS click Decrypt HTTPS traffic
4 Start Capture
5 Launch a browser
6 Navigate to the problem page and grid you would like to automate.
7 Stop Capture
8 Save Capture
9 Put the .SAZ file into a .zip file and attach that to this support ticket. 

Please note that this would only simulate your server behavior but will allow me inspect the structure of the Kendo grid. 

I am looking forward to hearing from you! Thanks! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 09 May 2017, 02:29 PM

Were you unable to build a sample per the code I provided?  What more do you need in order to be able to do that?

In a Kendo MVC project using Kendo.Mvc version 4.0.30319 (2016.3.1028.545), create a View that contains the code for the grid I provided, and in the controller for that view add a read function that contains the code for that which I provided, and have a SQL DB for it that contains some tables and a function similar to the code for querying the tables that I provided.  Then create a test project using ArtOfTest version 4.0.30319 (2017.1.207.0), and add a test containing the code for clicking in a cell in that grid that I provided (or like your demo).

I don't feel comfortable capturing decrypted traffic for you, as our site (and particularly that grid) contains sensitive customer information.  I have started trying to at least create a separate project that uses the same kind of stuff that I could send you...it's just taking some time as I have other duties.  But in the meantime if you would be able to do that just let me know what other info you need.  Thank you!

 

0
Tabatha
Top achievements
Rank 1
answered on 09 May 2017, 02:35 PM

Were you not able to build a sample using the code I provided?  What more do you need in order to be able to do that?

In a Kendo MVC project using Kendo.Mvc version 4.0.30319 (2016.3.1028.545), add a View that contains the code for the grid that I provided, and in the controller for that view add a read function with the code I provided for that, and have a SQL DB with some tables and a function for querying the tables like what I provided.  Then in a test project using ArtOfTest version 4.0.30319 (2017.1.207.0), add a test for clicking in a cell in that grid per the code for that I provided.

I do not feel comfortable sending you decrypted traffic from our site, as it contains sensitive customer information.  I did start putting together a separate project that uses the same stuff that I could send you, but it's taking some time as I have other things to do.  In the meantime if you would be able to try putting one together let me know what else you need for that.  Thank you!

0
Elena
Telerik team
answered on 11 May 2017, 01:41 PM
Hi Tabatha,

As you said it yourself setting up a project always takes time especially when there are many prerequisites to keep in mind.

I appreciate all provided details during the investigation. Since there is a working sample against the demo page we identified the issue is related to the particular application, its structure and the approach used to build it. On the other hand it might turn out that the demo project does not behave the same way despite of using the same setup. 

Therefore I suggested to use the Fiddler trace. You should keep in mind it is only simulation of the application server and will capture only what is navigated to during the Fiddler recording. Though I understand your concerns for data sensitivity and would like to inform you we could sign a NDA (non-disclosure agreement) for your convenience. 

Thank you for your understanding! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 18 May 2017, 06:56 PM

OK - I put a sample project together where the grid's Read function returns data in the same fashion as our application under test (with "return Content(jsonText, "application/json");").  I tried to attach it as a zip folder, but it's over 49 mb - is there a way to get it to you other than trying to attach it here?

Unfortunately, when I run from VS and I click the button to go to the page with the grid, it gives me error "Object doesn't support property or method 'kendoGrid'".  I referenced the answer here:  http://www.telerik.com/forums/object-doesn%27t-support-property-or-method-%27kendogrid%27   But I'm still getting the error.

So if I can manage to get you the project, then perhaps someone there can look into fixing that issue....and then if you can get it working and have a place to publish it, try using the test posted previously to see how many td cells the test framework thinks that grid has.  If it thinks there's only 1 (as in our application), I'm interested in why and if Telerik can fix the test framework so it will properly see the actual number of cells.

I'm also interested in if you were to change that function to return the data in the conventional fashion, if the test framework then sees the correct number of cells.  When I say that, I mean change Jobs_Active_Read to this:

            try {
                using (var db = new ApplicationDbContext())
                {
                    IQueryable<TfCustomerJobListReturnModel> jobs = db.TfCustomerJobList(CurrentUser.UserId, false);
                    DataSourceResult result = jobs.ToDataSourceResult(request);
                    return Json(result);
                }

            catch (Exception ex)
            {
                return null;
            }

 

Knowing that could help you guys pinpoint the issue in using the other way.  One would think that if our way works for populating the grid, it ought to work with the test framework as well.  And also I don't want to lose the protection against circular references, which is the reason for doing it the way we are (unless you have an alternative solution for that?).

Thank you!

0
Elena
Telerik team
answered on 23 May 2017, 12:46 PM
Hi Tabatha,

Thanks for your efforts. 

Here is a dropbox folder where you could share the project once you prepare it finally. I shared the folder to the listed email into this thread as well.

I will be looking forward to hearing from you once you manage to solve the error in project. Thanks!  

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Tabatha
Top achievements
Rank 1
answered on 24 May 2017, 05:24 PM

HI, Elena -

Thank you for the Dropbox link!  I am likely to end up using it, but not until we do some more investigating.  Here's what happened:

I learned that you can run a project from Visual Studio, and then just have the test navigate to its localhost URL to test it that way.  And I also managed to get my little sample project working.  So I went with both angles...I took our application-under-test and modified the grid's read function to return the data using your 'conventional' method to try my test on that, and I also tried my test on my sample project in which that grid's read function returns the data using the unconventional method in our application-under-test.  With the former, the test still reported only 1 td in the grid, while with the latter, it actually reported the number I expected (in this case, 20)!

So it turns out that there is something else that is different about our application-under-test that now we have to investigate, and we have my sample to compare against and test out theories in.  If we are able to come to a conclusion as to what it is that is different that's causing the test to only see 1 td, then I'll replicate it in the sample and send it to you.

0
Elena
Telerik team
answered on 29 May 2017, 11:37 AM
Hi Tabatha,

Thanks for the clarification. I am glad to hear you are few steps ahead. Do not hesitate to continue the communication on the topic in case of need. Thanks! 

Regards,
Elena Tsvetkova
Progress Telerik
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
Tags
General Discussions
Asked by
Tabatha
Top achievements
Rank 1
Answers by
Elena
Telerik team
Tabatha
Top achievements
Rank 1
Share this question
or