public WebDriver( IWebDriver seleniumDriver, Func <Uri> rootUrl, SeleniumGridConfiguration configuration, RetryExecutor retryExecutor, SelectorFactory selectorFactory, ElementFactory elementFactory, XpathProvider xpathProvider, MovieLogger movieLogger, WebElementSourceLog webElementSourceLog, IEnumerable <SelectorPrefix> prefixes = null) { SeleniumDriver = seleniumDriver; SuccessfulSearchers = new List <Searcher>(); RootUrl = rootUrl; SeleniumGridConfiguration = configuration; RetryExecutor = retryExecutor; SelectorFactory = selectorFactory; MovieLogger = movieLogger; Prefixes = prefixes?.ToList() ?? new List <SelectorPrefix>() { new EmptySelectorPrefix() }; Children = new List <WebDriver>(); Screenshots = new List <byte[]>(); ElementFactory = elementFactory; XpathProvider = xpathProvider; WebElementSourceLog = webElementSourceLog; }
public LoggingWebDriver(IWebDriver driver, MovieLogger movieLogger, WebElementSourceLog webElementSourceLog) { SeleniumDriver = driver; Messages = new List <string>(); Screenshots = new List <Screenshot>(); MovieLogger = movieLogger; WebElementSourceLog = webElementSourceLog; }
protected virtual void LogScreenshots() { if (MovieLogger.IsEnabled) { MovieLogger.ComposeMovie(); } WebElementSourceLog.Log(Logger); NetworkWatcher.Log(Logger); }
private void AugmentWebElementSources(Selector selector, IWebElement e) { var s = WebElementSourceLog.Get(e); if (s == null) { return; } s.SelectorType = selector.Type; s.SelectorConstructor = selector.Constructor; }
private Element FindElement(Selector selector, LoggingWebDriver loggingWebdriver, int?index = null) { var wrappers = selector.PrioritizedSearchers.Select(s => new Wrapper { Searcher = s }).ToList(); var loopResults = Parallel.ForEach(wrappers, //new ParallelOptions { MaxDegreeOfParallelism = 4 }, (wrapper, loopState) => { var searcher = wrapper.Searcher; var results = searcher.SearchIn(loggingWebdriver, Prefixes); if (loopState.ShouldExitCurrentIteration) { return; } else if (results.One()) { SuccessfulSearchers.Add(searcher); loopState.Break(); wrapper.Element = results.First(); return; } else if (results.Many() && index.HasValue) { SuccessfulSearchers.Add(searcher); loopState.Break(); var a = results.ToArray(); if (a.Count() <= index.Value) { wrapper.Exception = new Exception($"Not enough items found, found {a.Count()} and desired index {index}"); } else { wrapper.Element = a[index.Value]; } return; } else if (results.Many()) { var by = WebElementSourceLog.Get(results.First().WebElement).By; if (by.IsXpath()) { //lets find the only clickable one, //if two are precisely on top of each other it will not filter that //but that is unlikely to happen in real applications var el = FindOnlyClickable(by.Xpath()); if (el != null) { var pos = el.Location; var rpos = results.Select(x => new { x.Location, x }).ToList(); var filterHidden = rpos .Where(e => e.Location == pos) .Select(x => x.x); if (filterHidden.One()) { SuccessfulSearchers.Add(searcher); loopState.Break(); wrapper.Element = filterHidden.First(); return; } } } var items = results.Select(e => $"{e.Tag}@{e.Location.X},{e.Location.Y}").LogFormat(); loopState.Break(); wrapper.Exception = new Exception($"Multiple results were found using {searcher.LogFormat()}"); return; } }); var r = loopResults.IsCompleted; var wrapperIndex = 0; foreach (var w in wrappers) { if (w.Element != null) { AugmentWebElementSources(selector, w.Element.WebElement); return(w.Element); } if (w.Exception != null) { throw new AggregateException($"Error throw on xpath {wrapperIndex}", w.Exception); } wrapperIndex++; } return(null); }
protected virtual void SetupInfrastructure() { IConfiguration config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); NetworkWatcher = new NetworkWatcher(); var configFactory = new ConfigurationFactory(config); ObjectContainer.RegisterInstanceAs(configFactory.Create <MovieLoggerConfig>()); ObjectContainer.RegisterInstanceAs(configFactory.Create <ImageLoggingConfig>()); WebElementSourceLog = new WebElementSourceLog(); ImageLogging = new ImageLogging(ObjectContainer.Resolve <ImageLoggingConfig>()); Register(new FileManager(new DatetimeManager(() => DateTime.Now))); FileManager.Initialize(FeatureContext.FeatureInfo.Title, ScenarioContext.ScenarioInfo.Title, null /*Specflow limitation*/); MovieLogger = new MovieLogger(FileManager, ObjectContainer.Resolve <MovieLoggerConfig>(), Metadata); ObjectContainer.RegisterInstanceAs(ImageLogging); ObjectContainer.RegisterInstanceAs(MovieLogger); Logger = new DefaultLogger(new DirectoryInfo(Environment.CurrentDirectory), new YamlLogFormatter()); Register((PossumLabs.Specflow.Core.Logging.ILog)Logger); Register <ElementFactory>(new ElementFactory()); Register <XpathProvider>(new XpathProvider()); Register <SelectorFactory>(new SelectorFactory(ElementFactory, XpathProvider).UseBootstrap()); Register(new PossumLabs.Specflow.Selenium.WebDriverManager( this.Interpeter, this.ObjectFactory, new SeleniumGridConfiguration())); var dataGeneratorRepository = new DataGeneratorRepository(Interpeter, ObjectFactory); Register <DataGenerator>(dataGeneratorRepository.BuildGenerator()); var templateManager = new PossumLabs.Specflow.Core.Variables.TemplateManager(); templateManager.Initialize(Assembly.GetExecutingAssembly()); Register(templateManager); Log.Message($"feature: {FeatureContext.FeatureInfo.Title} scenario: {ScenarioContext.ScenarioInfo.Title} \n" + $"Tags: {FeatureContext.FeatureInfo.Tags.LogFormat()} {ScenarioContext.ScenarioInfo.Tags.LogFormat()}"); System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); WebDriverManager.Initialize(BuildDriver); WebDriverManager.WebDriverFactory = () => { var options = new ChromeOptions(); //grid options.AddAdditionalCapability("username", WebDriverManager.SeleniumGridConfiguration.Username, true); options.AddAdditionalCapability("accessKey", WebDriverManager.SeleniumGridConfiguration.AccessKey, true); var driver = new RemoteWebDriver(new Uri(WebDriverManager.SeleniumGridConfiguration.Url), options.ToCapabilities(), TimeSpan.FromSeconds(180)); //do not change this, the site is a bloody nightmare with overlaying buttons etc. driver.Manage().Window.Size = WebDriverManager.DefaultSize; var allowsDetection = driver as IAllowsFileDetection; if (allowsDetection != null) { allowsDetection.FileDetector = new LocalFileDetector(); } return(driver); }; }