Recent

Author Topic: Browser Automation with selenium  (Read 2237 times)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 824
Browser Automation with selenium
« on: June 05, 2020, 01:58:30 am »
hello,
i have found this library to do that with pascal language : Webdriver For Delphi lazarus.
The problem is that the lazarus part isn't done.
1 - the main problem is the json library used  in the unit Webdriver4D.pas : JsonDataObjects  . How to replace it with fcl-json and jsonparser ?
for example how to replace the code in brackets with the equivalent  of the fcl-json library :
Code: Pascal  [Select][+][-]
  1. function TWebDriver.ExecuteScript(const Script: string;
  2.   const Args: string = '[]'): string;
  3. var
  4.   Command: string;
  5.   Data: string;
  6.   Resp: string;
  7.   Json: TJsonObject;
  8. begin
  9.   Json := TJsonObject.Create;
  10.   try
  11.     Command := Host + '/session/' + FSessionID + '/execute/sync';
  12. {   Json.S['script'] := Script;
  13.     Json.A['args'].FromJSON(Args);
  14.     Data := Json.ToJSON();    }
  15.     Resp := ExecuteCommand(cPost, Command, Data);
  16.     result := ProcResponse(Resp);
  17.   Finally
  18.     FreeAndNil(Json);
  19.   end;
  20. end;            

Friendly, J.P
« Last Edit: June 05, 2020, 02:21:38 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Leledumbo

  • Hero Member
  • *****
  • Posts: 8266
  • Programming + Glam Metal + Tae Kwon Do = Me

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 824
Re: Browser Automation with selenium
« Reply #2 on: June 13, 2020, 02:34:04 pm »
hello,
thanks Leledumbo, i have found how to do that with  fpjson :
Code: Pascal  [Select][+][-]
  1. function TWebDriver.ExecuteScript(const Script: string;
  2.   const Args: string = '[]'): string;
  3. var
  4.   Command: string;
  5.   Data: string;
  6.   Resp: string;
  7.   Json: TJsonObject;
  8. begin
  9.   Json := TJsonObject.Create(['script', Script]);
  10.   try
  11.     Command := Host + '/session/' + FSessionID + '/execute/sync';
  12.     Json.Add('args',GETJson(Args));
  13.     Data := Json.AsJSON;
  14.     Resp := ExecuteCommand(cPost, Command, Data);
  15.     result := ProcResponse(Resp);
  16.   Finally
  17.     FreeAndNil(Json);
  18.   end;
  19. end;
I started a lazarus version of WebDriver4D ( name WebDriver4L) .
replace the delphi unit httpclient with the lazarus unit   fphttpclient
replace the delphi unit JsonDataObjects with the lazarus units fpson, jsonparser
version of WebDriver4L is alpha but it begins to work :
Example of code to open chrome and clear image and files cache  in  settings :
Code: Pascal  [Select][+][-]
  1. implementation
  2. uses  Webdriver4L;
  3. {$R *.lfm}
  4.  
  5. { TForm1 }
  6.  
  7. procedure TForm1.Button2Click(Sender: TObject);
  8. const CacheDlg = 'return document.querySelector(''settings-ui'')' +
  9.                  '.shadowRoot.querySelector(''settings-main'')' +
  10.                  '.shadowRoot.querySelector(''settings-basic-page'')' +
  11.                  '.shadowRoot.querySelector(''settings-section > settings-privacy-page'')' +
  12.                  '.shadowRoot.querySelector(''settings-clear-browsing-data-dialog'')';
  13. const btClear  = '.shadowRoot.querySelector(''#clearBrowsingDataDialog'')' +
  14.                  '.querySelector(''#clearBrowsingDataConfirm'')';
  15. const chkboxH1  = '.shadowRoot.querySelector(''iron-pages'')' +
  16.                   '.querySelector(''#browsingCheckboxBasic'')';
  17. const chkboxH2  = '.shadowRoot.querySelector(''iron-pages'')' +
  18.                   '.querySelector(''#cookiesCheckboxBasic'')';
  19. const chkboxH3  = '.shadowRoot.querySelector(''iron-pages'')' +
  20.                   '.querySelector(''#cacheCheckboxBasic'')';
  21. var Robot2 : TWebDriver;
  22.     Element : TWebElement;
  23. begin
  24.   Robot2 := TChromeDriver.Create(nil);
  25.   Robot2.StartDriver('chromedriver.exe');
  26.   Robot2.NewSession;
  27.   Robot2.Implicitly_Wait(1000);
  28.   Robot2.Set_Window_Size(640, 640);
  29.   Sleep(5000);
  30.   Robot2.GetURL('chrome://settings/clearBrowserData');
  31.   Sleep(2000);
  32.   Element := Robot2.FindElementByXPath('//settings-ui');
  33.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH1 + ';');
  34.   Memo1.Append('Etiquette case à cocher 1 : ' + Element.AttributeValue('label'));
  35.   if Element.PropertyValue('checked') = 'True' then  Element.Click();
  36.   Sleep(1000);
  37.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH2 + ';');
  38.   Memo1.Append('Etiquette case à cocher 2 : ' + Element.AttributeValue('label'));
  39.   if Element.PropertyValue('checked') = 'True' then  Element.Click();
  40.   Sleep(1000);
  41.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH3 + ';');
  42.   Memo1.Append('Etiquette case à cocher 3 : ' + Element.AttributeValue('label'));
  43.   if Element.PropertyValue('checked') = 'False' then  Element.Click();
  44.   Sleep(1000);
  45.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + btClear + ';');
  46.   Element.Click();
  47.   Sleep(30000);
  48.   Robot2.Clear;
  49. end;

Friendly, J.P
« Last Edit: June 13, 2020, 02:36:26 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 824
Re: Browser Automation with selenium
« Reply #3 on: June 15, 2020, 02:39:34 am »
hello,
now my alpha version of webdriver4L is working on linux (centos 8 - lazarus 2.0.8 ) . Screenshots work.
Code: Pascal  [Select][+][-]
  1. implementation
  2. uses  Webdriver4L;
  3. {$R *.lfm}
  4. { TForm1 }
  5. procedure TForm1.Button2Click(Sender: TObject);
  6. const CacheDlg = 'return document.querySelector(''settings-ui'')' +
  7.                  '.shadowRoot.querySelector(''settings-main'')' +
  8.                  '.shadowRoot.querySelector(''settings-basic-page'')' +
  9.                  '.shadowRoot.querySelector(''settings-section > settings-privacy-page'')' +
  10.                  '.shadowRoot.querySelector(''settings-clear-browsing-data-dialog'')';
  11. const btClear  = '.shadowRoot.querySelector(''#clearBrowsingDataDialog'')' +
  12.                  '.querySelector(''#clearBrowsingDataConfirm'')';
  13. const chkboxH1  = '.shadowRoot.querySelector(''iron-pages'')' +
  14.                   '.querySelector(''#browsingCheckboxBasic'')';
  15. const chkboxH2  = '.shadowRoot.querySelector(''iron-pages'')' +
  16.                   '.querySelector(''#cookiesCheckboxBasic'')';
  17. const chkboxH3  = '.shadowRoot.querySelector(''iron-pages'')' +
  18.                   '.querySelector(''#cacheCheckboxBasic'')';
  19. var Robot2 : TWebDriver;
  20.     Element : TWebElement;
  21.     png :  TPortableNetworkGraphic;
  22. begin
  23.   Robot2 := TChromeDriver.Create(nil);
  24.   Robot2.StartDriver('chromedriver');
  25.   Sleep(5000);
  26.   Robot2.NewSession;
  27.   Robot2.Implicitly_Wait(1000);
  28.   Robot2.Set_Window_Size(640, 640);
  29.   Robot2.GetURL('chrome://settings/clearBrowserData');
  30.   Sleep(2000);
  31.   Robot2.ScreenShot('clearBrowserData1.png');
  32.   Element := Robot2.FindElementByXPath('//settings-ui');
  33.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH1 + ';');
  34.   Memo1.Append('Etiquette case à cocher 1 : ' + Element.AttributeValue('label'));
  35.   if Element.PropertyValue('checked') = 'True' then  Element.Click();
  36.   Sleep(1000);
  37.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH2 + ';');
  38.   Memo1.Append('Etiquette case à cocher 2 : ' + Element.AttributeValue('label'));
  39.   if Element.PropertyValue('checked') = 'True' then  Element.Click();
  40.   Sleep(1000);
  41.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + chkboxH3 + ';');
  42.   Memo1.Append('Etiquette case à cocher 3 : ' + Element.AttributeValue('label'));
  43.   if Element.PropertyValue('checked') = 'False' then  Element.Click();
  44.   Sleep(1000);
  45.   Robot2.ScreenShot('clearBrowserData2.png');
  46.   Element.ElementData := Robot2.ExecuteScript(CacheDlg + btClear + ';');
  47.   Element.Click();
  48.   Application.ProcessMessages;
  49.   Sleep(10000);
  50.   Robot2.Clear;
  51.   png := TPortableNetworkGraphic.Create;
  52.   png.Assign(Self.GetFormImage);
  53.   png.SaveToFile('clearBrowserDataLazForm.png');
  54.   png.free;
  55. end;

Results in Attachments (click on the first attachment to see animation)

Friendly, J.P
« Last Edit: June 15, 2020, 02:41:17 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Blade

  • New Member
  • *
  • Posts: 44
Re: Browser Automation with selenium
« Reply #4 on: August 05, 2020, 06:57:00 pm »
This is very useful.  Thanks for sharing.

devEric69

  • Sr. Member
  • ****
  • Posts: 331
Re: Browser Automation with selenium
« Reply #5 on: August 06, 2020, 02:17:08 pm »
Hello @Jurassic Pork,

It's interesting to know.

Just for information, Selenium's successor is called Katalon (HMI web automation). It can use globally (i haven't looked at how deep compatible it is exactly) the same scripts as Selenium, which look like the ones coded as parameters in your Robot.ExecuteScript method.

Nevertheless, what is interesting to know, is that such version of a plugin (Selenium or Katalon) generally imposes a compatibility constraint, with a minimal version of a browser. Your solution is a way to get rid of it, if need be.
use: Linux 64 bits (Ubuntu 18.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

 

TinyPortal © 2005-2018