HtmlUnit / htmlunit

HtmlUnit is a "GUI-Less browser for Java programs".
https://www.htmlunit.org
Apache License 2.0
875 stars 172 forks source link

Clicking on hyperlink in column doesn't run ts linkTxt #324

Open lrpowell opened 3 years ago

lrpowell commented 3 years ago

The table column has a hyperlink for launching to the perspective graph:

1) in perspective-info.ts: For column w hyper link, an object is used to store the hyper link part and non-hyper link part. public persNameDisplayObj:{}=null;

in perspective-info-manager.ts: initializes this object tmpPersInfo.persNameDisplayObj = {linkTxt: tmpPersInfo.getPerspectiveName(), otherTxt: ""};

2) creating the table columns, a hyperlink property is used in perspectivee-list.component.ts:

 ngOnInit(): void {
      GlobalSetting.panelTitle = this.mriText.s('perf.dojo.table.title');
      this.initColumns();
      this.initActions();
      this.getData();
  }

  initColumns(): void {
      this.columnsDefault = [
          { field: 'packageName', header: this.mriText.s('perf.dojo.package.name'),selected:true, sortable:true},
          **{ field: 'perspectiveName', header: this.mriText.s('perf.dojo.perspective.name'),selected:true, sortable:true, _hyperlink:"persNameDisplayObj"_},**
          { field: 'description', header: this.mriText.s('perf.dojo.description') ,selected:true, sortable:true},
          { field: 'viewName', header: this.mriText.s('perf.dojo.view.name') ,selected:true, sortable:true},
          { field: 'metrics', header: this.mriText.s('perf.dojo.metrics'),selected:true, sortable:true },
          { field: 'sql', header: this.mriText.s('perf.dojo.sql'),selected:true, sortable:true, hyperlink:"sqlDisplayObj"}
      ];
  }

 **onLinkClick($event): void{**
      console.log($event);
      let rowData = $event.row;
      let col = $event.col;
      **if(col == 'persNameDisplayObj'){
          this.gotoDojoGraph(rowData);**
      }else if(col == 'sqlDisplayObj'){
          this.viewSQLDetail.sqlCmd = rowData.getFullSql();
          this.viewSQLDetail.showSql();
      }
  }

  **gotoDojoGraph**(rowData): void {
      console.log(rowData);
      let pInfo = rowData;
      this.router.navigate(['/mainframe/performance/dojo-graph'], { state: {
          packageId: pInfo.getPackageId(),
          perspectiveId: pInfo.getPerspectiveId(),
          **perspectiveName: pInfo.getPerspectiveName(),**
          collectionLib: pInfo.getCollectionLib(),
          collectionName: pInfo.getCollectionName(),
          collectionType: pInfo.getCollectionType(),
          collectionFormat: pInfo.getCollectionFormat(),
          fileLevel: pInfo.getFileLevel(),
          startTime: pInfo.getStartTime(),
          endTime: pInfo.getEndTime(),
          systemName: pInfo.getSystemName(),
          release: pInfo.getRelease()
      } });
  }

3) basictable.component.html defines the column with hyper link: <span *ngIf="col.hyperlink" style="vertical-align:middle;">{{rowData[col.hyperlink].otherTxt}}<a href="javascript:void(0);"(click)= "onLinkClick.emit({row:rowData,col:col.hyperlink})">{{rowData[col.hyperlink].linkTxt}}</a></span>

Above for the column in basictable, "javascript:vodi(0)" means we go nowhere but execute the click function. So here the onLinkClick() function is triggered and passed the perspective info and hyper link object name as parameters.

4) When clicked in the browser, the onLinkClick() function invokes gotoDojoGraph() method with the perspective name information and the router routes to the "dojo-graph" path. The component DojoGraphLauncher(dojo.graph.launcher.ts) is then invoked

5) In the gotoDojoGraph() function, the router routes to the "dojo-graph" path, and its corresponding component is DojoGraphLauncher(dojo.graph.launcher.ts). All the routing configuration info are stored in performance.routing.module.ts:

      {
        path: 'dojo-graph',
        component: DojoGraphLauncher
      },

6) The template of DojoGraphLauncher component is dojo.graph.launcher.html. The DojoGraphLauncher object is constructed with the perspective info passed in and in the ngOnInit() function it finally loads our js script DojoGraphLauncher.js. In the js, it loads all the dojo classes and parses the dojo widgets in dojo.graph.launcher.html and finally calls DojoGraph.js.

7) In DojoGraph.js, it will send request to the server side and get the data to render on the chart by sending an Ajax request with the url: url = "/Navigator/DispatcherServlet/perf/dojoChartRequestHandler?f=getData"

The servlet will find the controller class PerformanceController by this part:

 @RequestMapping("/DispatcherServlet/perf")
    public class PerformanceController extends BaseController {

In PerformanceController, it will find the method dojoChartRequestHandler to handle this request:

    @RequestMapping("/dojoChartRequestHandler")
    public ResponseObject dojoChartRequestHandler() {

8) In dojoChartRequestHandler(), PerspectiveManager.chartRequestHandler() is called all requests. It passes the real class to handle the dojo chart request as a parameter: GraphDataProvider in pt.guix.jar.

9). The chart data will be returned to the DojoGraph.js from the getData() function of GraphDataProvider directly.

Doing a click on this element in HtmlUnit does not end up activating this same code.

Is there a way to determine why the onLinkClick() and gotoDojoGraph() methods are not being processed when calling "click()" for the table element?

On the page we are processing with the table and perspective names, this is the element we want to "click on";

<a _ngcontent-ogg-c139="" href="javascript:void(0);">
  CPU Utilization (Average)
</a>

For a page like this, we can select one of the items in the 2nd column (CPU Utilization (Average) or "Database Health Indicators"), or alternatively we can do the pop-up menu and select "Investigate Data" which should launch the same chart for whatever row we are hovered over ("Disk Health Indicators" in this screenshot).

Screen Shot 2021-03-05 at 4 51 19 PM

Here is a full row: NewFile.xml.txt

Is there something else that needs to be done for the click to be activated in this situation? I gave you I think a lot more information that may be needed to make sure the whole setup was defined. If you need clarification on anything just ask.

lrpowell commented 3 years ago

This is my most significant blocker at this time for the project. I will try to use the pop up menu to select to launch to this link.

Some more information on the link itself and debugging it in typescript trying to understand why we cannot see the onclick when debugging and determining if this is a reason why the click function is not run with HtmlUnit:

This functions the same as other widgets that can accept clicking event, such as the refresh icon at the up right corner of the table. It also has a (click) in the html:

<div class="ui-toolbar-group-right" style="margin-left:3px">
            <img (**click**)="onRefresh()" src="images/refresh.png" style="cursor:pointer;height:16px;margin-top:5px;" nav-popover="{{mriText.s('refresh')}}" alt="{{mriText.s('refresh')}}"/>
</div>

But in the debug console of the browser, (onclick) is missing too:

image

I do not know how angular integrates and generates the html that shown in the browser. And whether it is related to this problem of no response when clicking the link with HtmlUnit. I will try clicking the refresh button to see if that works with HtmlUnit next.

rbri commented 3 years ago

Hi Lora,

thanks for the detailed description. At the moment i have no real idea what is going wrong here - as always is there something in the logs?

Another option is to force HtmlUnit to ignore the visibility - sometimes HtmlUnit thinks the control is not visible and because of this the click is not processed. See #301 for details.

lrpowell commented 3 years ago

I have tried the full click line as is done if the element is not visible: anchor.click(false, false, false, true, true, false); with no different results.
Attached is my output when I set to output ALL java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.ALL); RunPDIReport.docx

There isn't any output indicating that the "click" was not activated for any reason. interesting messages Lots of these:

Mar 23, 2021 3:53:12 PM com.gargoylesoftware.htmlunit.IncorrectnessListenerImpl notify WARNING: Obsolete content type encountered: 'application/x-javascript'.

plenty of variations on CSS warnings/errors:

Mar 23, 2021 3:53:37 PM com.gargoylesoftware.htmlunit.DefaultCssErrorHandler error WARNING: CSS error: 'http://localhost:9080/Navigator/mainframe/home' [21:22] Error in style rule. (Invalid token "\"". Was expecting one of: < EOF >, < S >, < IDENT >, "}", ";", "*", < CUSTOM_PROPERTY_NAME >.) Mar 23, 2021 3:53:37 PM com.gargoylesoftware.htmlunit.DefaultCssErrorHandler warning WARNING: CSS warning: 'http://localhost:9080/Navigator/mainframe/home' [21:22] Ignoring the following declarations in this rule.

later more similar CSS errors and warnings:

Mar 23, 2021 3:54:02 PM com.gargoylesoftware.htmlunit.DefaultCssErrorHandler error WARNING: CSS error: 'http://localhost:9080/Navigator/mainframe/performance/dojo-graph' [1:2] Error in class selector. (Invalid token ".". Was expecting: < IDENT >.) Mar 23, 2021 3:54:02 PM com.gargoylesoftware.htmlunit.DefaultCssErrorHandler warning WARNING: CSS warning: 'http://localhost:9080/Navigator/mainframe/performance/dojo-graph' [1:2] Ignoring the whole rule.

Plenty of these:

Mar 23, 2021 3:53:37 PM com.gargoylesoftware.htmlunit.javascript.host.canvas.CanvasRenderingContext2D setLineDash INFO: CanvasRenderingContext2D.setLineDash() not yet implemented and

Mar 23, 2021 3:53:37 PM com.gargoylesoftware.htmlunit.javascript.host.canvas.rendering.AwtRenderingBackend extractColor INFO: Can not find color 'rgba(0,0,0,0.25)'

after SEVERE errors (parser error as posted in issue #318 ) it keeps going but no LOADING is ever found or resolved and perspective is not displayed because click on Link above doesn't happen...

rbri commented 3 years ago

Hi Lora, i was on vacation for some days - sorry for not working on this.

Just as an idea - maybe the event is assigned to some element in the shadow dom?

lrpowell commented 3 years ago

I will ask a team member. I don't see anything related to the shadow dom, but not sure what to look for.

lrpowell commented 3 years ago

Angular, does supports shadow dom when creating a component, but we haven't utilized this option in our code. By default, Angular operates dom directly. I have searched the html/xml for any #shadow and nothing is there.

rbri commented 3 years ago

maybe related to #346?