|
20 | 20 | using System.Collections.Generic; |
21 | 21 | using System.Collections.ObjectModel; |
22 | 22 | using System.Drawing; |
23 | | -using OpenQA.Selenium.Internal; |
24 | 23 |
|
25 | 24 | namespace OpenQA.Selenium.Support.Events |
26 | 25 | { |
@@ -101,6 +100,16 @@ public EventFiringWebDriver(IWebDriver parentDriver) |
101 | 100 | /// </summary> |
102 | 101 | public event EventHandler<FindElementEventArgs> FindElementCompleted; |
103 | 102 |
|
| 103 | + /// <summary> |
| 104 | + /// Fires before the driver starts to get a shadow root. |
| 105 | + /// </summary> |
| 106 | + public event EventHandler<GetShadowRootEventArgs> GettingShadowRoot; |
| 107 | + |
| 108 | + /// <summary> |
| 109 | + /// Fires after the driver completes getting a shadow root. |
| 110 | + /// </summary> |
| 111 | + public event EventHandler<GetShadowRootEventArgs> GetShadowRootCompleted; |
| 112 | + |
104 | 113 | /// <summary> |
105 | 114 | /// Fires before a script is executed. |
106 | 115 | /// </summary> |
@@ -728,6 +737,30 @@ protected virtual void OnFindElementCompleted(FindElementEventArgs e) |
728 | 737 | } |
729 | 738 | } |
730 | 739 |
|
| 740 | + /// <summary> |
| 741 | + /// Raises the <see cref="OnGettingShadowRoot"/> event. |
| 742 | + /// </summary> |
| 743 | + /// <param name="e">A <see cref="GetShadowRootEventArgs"/> that contains the event data.</param> |
| 744 | + protected virtual void OnGettingShadowRoot(GetShadowRootEventArgs e) |
| 745 | + { |
| 746 | + if (this.GettingShadowRoot != null) |
| 747 | + { |
| 748 | + this.GettingShadowRoot(this, e); |
| 749 | + } |
| 750 | + } |
| 751 | + |
| 752 | + /// <summary> |
| 753 | + /// Raises the <see cref="OnGetShadowRootCompleted"/> event. |
| 754 | + /// </summary> |
| 755 | + /// <param name="e">A <see cref="GetShadowRootEventArgs"/> that contains the event data.</param> |
| 756 | + protected virtual void OnGetShadowRootCompleted(GetShadowRootEventArgs e) |
| 757 | + { |
| 758 | + if (this.GetShadowRootCompleted != null) |
| 759 | + { |
| 760 | + this.GetShadowRootCompleted(this, e); |
| 761 | + } |
| 762 | + } |
| 763 | + |
731 | 764 | /// <summary> |
732 | 765 | /// Raises the <see cref="ScriptExecuting"/> event. |
733 | 766 | /// </summary> |
@@ -1613,7 +1646,11 @@ public ISearchContext GetShadowRoot() |
1613 | 1646 | ISearchContext shadowRoot = null; |
1614 | 1647 | try |
1615 | 1648 | { |
| 1649 | + GetShadowRootEventArgs e = new GetShadowRootEventArgs(this.parentDriver.WrappedDriver, this.underlyingElement); |
| 1650 | + this.parentDriver.OnGettingShadowRoot(e); |
1616 | 1651 | shadowRoot = this.underlyingElement.GetShadowRoot(); |
| 1652 | + this.parentDriver.OnGetShadowRootCompleted(e); |
| 1653 | + shadowRoot = new EventFiringShadowRoot(this.parentDriver, shadowRoot); |
1617 | 1654 | } |
1618 | 1655 | catch (Exception ex) |
1619 | 1656 | { |
@@ -1726,5 +1763,121 @@ public override int GetHashCode() |
1726 | 1763 | return this.underlyingElement.GetHashCode(); |
1727 | 1764 | } |
1728 | 1765 | } |
| 1766 | + |
| 1767 | + /// <summary> |
| 1768 | + /// EventFiringShadowElement allows you to have access to specific shadow elements |
| 1769 | + /// </summary> |
| 1770 | + private class EventFiringShadowRoot : ISearchContext, IWrapsDriver |
| 1771 | + { |
| 1772 | + private ISearchContext underlyingSearchContext; |
| 1773 | + private EventFiringWebDriver parentDriver; |
| 1774 | + |
| 1775 | + /// <summary> |
| 1776 | + /// Initializes a new instance of the <see cref="EventFiringShadowRoot"/> class. |
| 1777 | + /// </summary> |
| 1778 | + /// <param name="driver">The <see cref="EventFiringWebDriver"/> instance hosting this element.</param> |
| 1779 | + /// <param name="searchContext">The <see cref="ISearchContext"/> to wrap for event firing.</param> |
| 1780 | + public EventFiringShadowRoot(EventFiringWebDriver driver, ISearchContext searchContext) |
| 1781 | + { |
| 1782 | + this.underlyingSearchContext = searchContext; |
| 1783 | + this.parentDriver = driver; |
| 1784 | + } |
| 1785 | + |
| 1786 | + /// <summary> |
| 1787 | + /// Gets the underlying wrapped <see cref="ISearchContext"/>. |
| 1788 | + /// </summary> |
| 1789 | + public ISearchContext WrappedSearchContext |
| 1790 | + { |
| 1791 | + get { return this.underlyingSearchContext; } |
| 1792 | + } |
| 1793 | + |
| 1794 | + /// <summary> |
| 1795 | + /// Gets the underlying parent wrapped <see cref="IWebDriver"/> |
| 1796 | + /// </summary> |
| 1797 | + public IWebDriver WrappedDriver |
| 1798 | + { |
| 1799 | + get { return this.parentDriver; } |
| 1800 | + } |
| 1801 | + |
| 1802 | + /// <summary> |
| 1803 | + /// Finds the first element in the page that matches the <see cref="By"/> object |
| 1804 | + /// </summary> |
| 1805 | + /// <param name="by">By mechanism to find the element</param> |
| 1806 | + /// <returns>IWebElement object so that you can interaction that object</returns> |
| 1807 | + public IWebElement FindElement(By by) |
| 1808 | + { |
| 1809 | + IWebElement wrappedElement = null; |
| 1810 | + try |
| 1811 | + { |
| 1812 | + GetShadowRootEventArgs e = new GetShadowRootEventArgs(this.parentDriver.WrappedDriver, this.underlyingSearchContext); |
| 1813 | + this.parentDriver.OnGettingShadowRoot(e); |
| 1814 | + IWebElement element = this.underlyingSearchContext.FindElement(by); |
| 1815 | + this.parentDriver.OnGetShadowRootCompleted(e); |
| 1816 | + wrappedElement = new EventFiringWebElement(this.parentDriver, element); |
| 1817 | + } |
| 1818 | + catch (Exception ex) |
| 1819 | + { |
| 1820 | + this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex)); |
| 1821 | + throw; |
| 1822 | + } |
| 1823 | + |
| 1824 | + return wrappedElement; |
| 1825 | + } |
| 1826 | + |
| 1827 | + /// <summary> |
| 1828 | + /// Finds the elements on the page by using the <see cref="By"/> object and returns a ReadOnlyCollection of the Elements on the page |
| 1829 | + /// </summary> |
| 1830 | + /// <param name="by">By mechanism to find the element</param> |
| 1831 | + /// <returns>ReadOnlyCollection of IWebElement</returns> |
| 1832 | + public ReadOnlyCollection<IWebElement> FindElements(By by) |
| 1833 | + { |
| 1834 | + List<IWebElement> wrappedElementList = new List<IWebElement>(); |
| 1835 | + try |
| 1836 | + { |
| 1837 | + GetShadowRootEventArgs e = new GetShadowRootEventArgs(this.parentDriver.WrappedDriver, this.underlyingSearchContext); |
| 1838 | + this.parentDriver.OnGettingShadowRoot(e); |
| 1839 | + ReadOnlyCollection<IWebElement> elements = this.underlyingSearchContext.FindElements(by); |
| 1840 | + this.parentDriver.OnGetShadowRootCompleted(e); |
| 1841 | + foreach (IWebElement element in elements) |
| 1842 | + { |
| 1843 | + IWebElement wrappedElement = this.parentDriver.WrapElement(element); |
| 1844 | + wrappedElementList.Add(wrappedElement); |
| 1845 | + } |
| 1846 | + } |
| 1847 | + catch (Exception ex) |
| 1848 | + { |
| 1849 | + this.parentDriver.OnException(new WebDriverExceptionEventArgs(this.parentDriver, ex)); |
| 1850 | + throw; |
| 1851 | + } |
| 1852 | + |
| 1853 | + return wrappedElementList.AsReadOnly(); |
| 1854 | + } |
| 1855 | + |
| 1856 | + /// <summary> |
| 1857 | + /// Determines whether the specified <see cref="EventFiringShadowRoot"/> is equal to the current <see cref="EventFiringShadowRoot"/>. |
| 1858 | + /// </summary> |
| 1859 | + /// <param name="obj">The <see cref="EventFiringWebElement"/> to compare to the current <see cref="EventFiringShadowRoot"/>.</param> |
| 1860 | + /// <returns><see langword="true"/> if the specified <see cref="EventFiringShadowRoot"/> is equal to the current <see cref="EventFiringShadowRoot"/>; otherwise, <see langword="false"/>.</returns> |
| 1861 | + public override bool Equals(object obj) |
| 1862 | + { |
| 1863 | + ISearchContext other = obj as ISearchContext; |
| 1864 | + |
| 1865 | + if (other == null) |
| 1866 | + { |
| 1867 | + return false; |
| 1868 | + } |
| 1869 | + |
| 1870 | + return underlyingSearchContext.Equals(other); |
| 1871 | + } |
| 1872 | + |
| 1873 | + /// <summary> |
| 1874 | + /// Return the hash code for this <see cref="EventFiringWebElement"/>. |
| 1875 | + /// </summary> |
| 1876 | + /// <returns>A 32-bit signed integer hash code.</returns> |
| 1877 | + public override int GetHashCode() |
| 1878 | + { |
| 1879 | + return this.underlyingSearchContext.GetHashCode(); |
| 1880 | + } |
| 1881 | + } |
1729 | 1882 | } |
1730 | 1883 | } |
0 commit comments