You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
10 KiB

  1. namespace SeleniumBrowser.Command
  2. {
  3. using OpenQA.Selenium.Support.UI;
  4. using OpenQA.Selenium;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Threading;
  8. using System.Windows.Forms;
  9. using System.Collections.ObjectModel;
  10. using System.Drawing;
  11. using log4net;
  12. public class CommandInfo
  13. {
  14. private readonly static ILog _log = LogManager.GetLogger(typeof(CommandInfo));
  15. public const string ID = "id";
  16. public const string CLASSNAME = "classname";
  17. public const string XPATH = "xpath";
  18. public const string LINKTEXT = "linktext";
  19. public const string NAME = "name";
  20. public const string EVENT_CLICK = "click";
  21. public const string EVENT_FILL = "fill";
  22. public const string EVENT_SETURL = "seturl";
  23. public const string EVENT_SENDKEY = "sendkey";
  24. public const string EVENT_PASTE = "paste";
  25. public const string EVENT_SLEEP = "sleep";
  26. public delegate string DgHandler(IWebDriver i_uwdBrowser, IWebElement i_iweTarget, ref ConcurrentDictionary<string, object> i_cdGlobalData);
  27. internal CommanderGlobalData BatchProcessData { get; set; }
  28. public string Command { get; set; }
  29. public int WaitTargetSecond { get; set; } = 10;
  30. public int TargetNo { get; set; } = 0;
  31. public string Target
  32. {
  33. get { return _target; }
  34. set
  35. {
  36. _target = value;
  37. if (_target != null)
  38. {
  39. int nIdx = _target.IndexOf('=', StringComparison.OrdinalIgnoreCase);
  40. targetType = _target.Substring(0, nIdx);
  41. targetValue = _target.Substring(nIdx + 1);
  42. }
  43. else
  44. {
  45. targetType = null;
  46. targetValue = null;
  47. }
  48. }
  49. }
  50. private string _target;
  51. protected string targetType { get; private set; }
  52. protected string targetValue { get; private set; }
  53. public string Value { get; set; }
  54. public int SleepAfterEvent { get; set; } = 1;
  55. protected string click(IWebDriver i_uwdBrowser, IWebElement i_iweTarget, ref ConcurrentDictionary<string, object> i_cdGlobalData)
  56. {
  57. string sMsg = null;
  58. do
  59. {
  60. string sFilePath = System.IO.Path.Combine(BatchProcessData.StotrFolder, $"{BatchProcessData.CommandCount:000}.png");
  61. string sStepFilePath = System.IO.Path.Combine(BatchProcessData.StotrFolder, $"Step_{BatchProcessData.CommandCount:000}.png");
  62. lock (i_uwdBrowser)
  63. {
  64. (i_uwdBrowser as ITakesScreenshot).GetScreenshot().SaveAsFile(sFilePath);
  65. }
  66. System.Diagnostics.Debug.WriteLine(i_iweTarget.Location);
  67. StringFormat stringFormat = new StringFormat
  68. {
  69. Alignment = StringAlignment.Center,
  70. LineAlignment = StringAlignment.Center
  71. };
  72. Image i = Image.FromFile(sFilePath);
  73. BatchProcessData.StepCount++;
  74. using (var graphics = Graphics.FromImage(i))
  75. {
  76. int width = 50;
  77. int height = 50;
  78. Rectangle rHeader = new Rectangle() { X = i_iweTarget.Location.X - width, Y = i_iweTarget.Location.Y - height, Width = width, Height = height };
  79. graphics.FillEllipse(new SolidBrush(Color.Red), rHeader.X, rHeader.Y, rHeader.Width, rHeader.Height);
  80. graphics.DrawString($"{BatchProcessData.StepCount}", new Font(FontFamily.GenericMonospace, 24.0F,
  81. FontStyle.Italic, GraphicsUnit.Pixel), new SolidBrush(Color.White), rHeader, stringFormat);
  82. }
  83. i.Save(sStepFilePath);
  84. i_iweTarget?.Click();
  85. }
  86. while (false);
  87. return sMsg;
  88. }
  89. protected string fill(IWebDriver i_uwdBrowser, IWebElement i_iweTarget, ref ConcurrentDictionary<string, object> i_cdGlobalData)
  90. {
  91. string sMsg = null;
  92. do
  93. {
  94. i_iweTarget?.SendKeys(Value);
  95. }
  96. while (false);
  97. return sMsg;
  98. }
  99. public string Process(IWebDriver i_uwdBrowser, ref ConcurrentDictionary<string, object> i_cdGlobalData,
  100. [System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
  101. [System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = null,
  102. [System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = null)
  103. {
  104. string sMsg = null;
  105. try
  106. {
  107. do
  108. {
  109. if (i_uwdBrowser == null)
  110. {
  111. sMsg = "NO_BROWSER";
  112. break;
  113. }
  114. _log.Debug(Command);
  115. switch (Command)
  116. {
  117. case EVENT_CLICK:
  118. sMsg = wait(i_uwdBrowser, ref i_cdGlobalData, click);
  119. break;
  120. case EVENT_FILL:
  121. sMsg = wait(i_uwdBrowser, ref i_cdGlobalData, fill);
  122. break;
  123. case EVENT_SETURL:
  124. {
  125. i_uwdBrowser.Url = Value;
  126. }
  127. break;
  128. case EVENT_SENDKEY:
  129. {
  130. SendKeys.Send(Value);
  131. }
  132. break;
  133. case EVENT_PASTE:
  134. {
  135. Clipboard.SetText(Value);
  136. SendKeys.Send("^{v}");
  137. }
  138. break;
  139. case EVENT_SLEEP:
  140. {
  141. if (SleepAfterEvent > 0)
  142. {
  143. Thread.Sleep(SleepAfterEvent * 1000);
  144. }
  145. }
  146. break;
  147. default:
  148. sMsg = $"NOT SUPPORT Command '{Command}'";
  149. break;
  150. }
  151. if (sMsg != null)
  152. {
  153. break;
  154. }
  155. if (SleepAfterEvent > 0)
  156. {
  157. Thread.Sleep(SleepAfterEvent * 1000);
  158. }
  159. }
  160. while (false);
  161. }
  162. catch (Exception ex)
  163. {
  164. sMsg = $"{typeof(CommandInfo).Name} unhandle exception. Call from {i_sMemberName} {i_sSourcePath}({i_nCodeLine}).";
  165. #if DEBUG
  166. sMsg += ex.Message;
  167. #endif
  168. }
  169. #if DEBUG
  170. if (sMsg != null)
  171. {
  172. System.Diagnostics.Debug.WriteLine(sMsg);
  173. }
  174. #endif
  175. return sMsg;
  176. }
  177. protected By getTargetBy()
  178. {
  179. By byRes = null;
  180. switch (targetType.ToLower())
  181. {
  182. case ID:
  183. byRes = By.Id(targetValue);
  184. break;
  185. case CLASSNAME:
  186. byRes = By.ClassName(targetValue);
  187. break;
  188. case XPATH:
  189. byRes = By.XPath(targetValue);
  190. break;
  191. case NAME:
  192. byRes = By.Name(targetValue);
  193. break;
  194. case LINKTEXT:
  195. byRes = By.LinkText(targetValue);
  196. break;
  197. default:
  198. throw new NotImplementedException($"Not support type of{targetType}");
  199. }
  200. return byRes;
  201. }
  202. protected string wait(IWebDriver i_uwdBrowser, ref ConcurrentDictionary<string, object> i_cdGlobalData, DgHandler i_dgHandler)
  203. {
  204. string sMsg = null;
  205. IWebElement iweTarget = null;
  206. try
  207. {
  208. do
  209. {
  210. By byItem = getTargetBy();
  211. if (WaitTargetSecond > 0)
  212. {
  213. #if DEBUG
  214. System.Diagnostics.Debug.WriteLine($"[{DateTime.Now}] Waiting for '{byItem}' begin");
  215. #endif
  216. var wait = new WebDriverWait(i_uwdBrowser, TimeSpan.FromSeconds(WaitTargetSecond));
  217. if (targetType == ID)
  218. {
  219. iweTarget = wait.Until((drv => drv.FindElement(byItem)));
  220. }
  221. else
  222. {
  223. ReadOnlyCollection<IWebElement> iwes = wait.Until((drv => drv.FindElements(byItem)));
  224. if (iwes != null && iwes.Count > TargetNo)
  225. {
  226. iweTarget = iwes[TargetNo];
  227. }
  228. }
  229. #if DEBUG
  230. System.Diagnostics.Debug.WriteLine($"[{DateTime.Now}] Waiting for '{byItem}' end");
  231. #endif
  232. }
  233. else
  234. {
  235. if (targetType == ID)
  236. {
  237. iweTarget = i_uwdBrowser.FindElement(byItem);
  238. }
  239. else
  240. {
  241. ReadOnlyCollection<IWebElement> iwes = i_uwdBrowser.FindElements(byItem);
  242. if (iwes != null && iwes.Count <= TargetNo)
  243. {
  244. iweTarget = iwes[TargetNo];
  245. }
  246. }
  247. }
  248. } while (false);
  249. if (iweTarget == null)
  250. {
  251. sMsg = $"WAIT_FAIL({Target}:{TargetNo})";
  252. }
  253. }
  254. catch (Exception ex)
  255. {
  256. sMsg = $"WAIT_FAIL({Target})";
  257. #if DEBUG
  258. sMsg += ex.Message;
  259. #endif
  260. }
  261. if (sMsg == null && i_dgHandler != null)
  262. {
  263. sMsg = i_dgHandler(i_uwdBrowser, iweTarget, ref i_cdGlobalData);
  264. }
  265. return sMsg;
  266. }
  267. }
  268. }