Releases: yashaka/NSelene
Releases · yashaka/NSelene
1.0.0-alpha14
- add Configuration.LogOuterHtmlOnFailure (false by default)
- to disable previously mandatory logging of outer html of elements in error messages
that was the reason of failures when working with Appium
- to disable previously mandatory logging of outer html of elements in error messages
1.0.0-alpha13
- fix element.GetAttribute to call webelement.GetAttribute instead of webelement.GetDomAttribute
- correspondingly the behavior of element.Value is also fixed, becaused is based on element.GetAttribute
1.0.0-alpha12
Selenium 4.17+ and BaseUrl in config
- upgraded Selenium.WebDriver to 4.* (i.e. to 4.17.0 as of 2024.02.09)
- WDM is not used anymore in NSelene examples and removed from README
since Selenium Manager is in charge of managing drivers now
- WDM is not used anymore in NSelene examples and removed from README
- added Configuration.BaseUrl, thanks to @davespoon
- added Have.AttributeWithValue* conditions, thanks to @davespoon
v1.0.0-alpha11
collection.ElementByIts(innerLocator, condition)
- upgraded Selenium.WebDriver from from 4.2.0 to 4.9.1
collection.ElementBy(condition)
alias tocollection.FindBy(condition)
FindBy
will be probably deprecated in future
collection.By(condition)
alias tocollection.FilterBy(condition)
FilterBy
will be probably deprecated in future
element.Element(locator | selector)
alias toelement.Find(locator | selector)
Find
will be probably deprecated in future
element.All(locator | selector)
alias toelement.FindAll(locator | selector)
FindAll
will be probably deprecated in future
Should(driverCondition)
alias toWaitTo(driverCondition)
- conditions: Have.Url, .UrlContaining, Title, TitleContaining
- collection.ElementByIts(locator | selector, condition)
- so you can implement something like this:
SS(".table-row").ElementByIts(".table-cell[role=name]", Have.Text("John")).Element("[role=remove-user]").Click()
- so you can implement something like this:
upgraded Selenium.WebDriver from 3.141.0 to 4.2.0
- upgraded Selenium.WebDriver from 3.141.0 to 4.2.0
- kept old-fashioned names for SeleneElement.GetAttribute & .GetProperty
but now under the hood they use new GetDomAttribute & GetDomProperty correspondingly - added SeleneElement.GetShadowRoot as wrapper over WebElement.GetShadowRoot
- kept old-fashioned names for SeleneElement.GetAttribute & .GetProperty
Improved errors for inner search and fixed _HookWaitAction in Should
- improved error messages for cases of inner element search
- like error on S(".parent").Find(".child").Click() when .parent is absent or not visible
- FIXED experimental Configuration._HookWaitAction application to Should methods on SeleneElement and SeleneCollection
(was not working, just being skipped)
Waiting for SeleneElementJsExtensions
Added waiting to SeleneElementJsExtensions
- JsClick
- JsType
- JsSetValue
Improved conditions logging in errors and first experimental waiting hooks
- improved error messsages
- now condition in Should method will be rendered like:
... .Should(Be.Visible)
over just... .Visible
- now condition in Should method will be rendered like:
- deprecated SeleneElement#config, use SeleneElement#Config instead (same for SeleneCollection)
- yet be attentive... the fate of keeping SeleneElement#Config as public is also vague...
- added experimental feature: Configuration._HookWaitAction
- prefixed with underscore implies that this feature is kind of "publically available private property that might be changed/renamed/removed/etc in future;)", so use it on your own risk!!!
- by default equals to null, making internally call waiting algorithm for actions as it is, without additional customization
- specified to something like:
Configuration._HookWaitAction = (entity_object, describe_computation, wait) => { Console.WriteLine($"STARTED WAITING FOR: {entity_object}.{describe_computation()}"); try { wait(); Console.WriteLine($"FINISHED WAITING FOR: {entity_object}.{describe_computation()}"); } catch (Exception error) { Console.WriteLine($"FAILED WAITING FOR: {entity_object}.{describe_computation()}"); throw error; } };
- should provide some additinal logging for all Selene actions, called on entities (like SeleneElement, SeleneCollection)
- under actions we mean "void commands" not "queries returning result".
- void command like element.Should(condition) will return the element itself instead of void ;)
turned off automatic Configuration.WaitForNoOverlapFoundByJs by default
- turned off "waiting for no overlay" that was built-in in alpha05 in all actions. (#85)
- cause it could break some NSelene + Appium mobile tests that can't use JS, while this waiting was built on top of JS so it's relevant only for web...
- yet the Configuration.WaitForNoOverlapFoundByJs was added (false by default)
- so you can turn it on globally by Configuration.WaitForNoOverlapFoundByJs = true
- or per element by element.With(waitForNoOverlapFoundByJs: true)
- in future we might made this waiting enabled by default, when we provide better docs and plugins to work with Appium
- added rendering of elements under overlay into errors (#84)
- made rendering elements HTML – lazy (when waiting for no overlap)
- should improve performance in context of polling during waiting
- made rendering elements HTML – lazy (when waiting for no overlap)
Faster, full unti-flakyness, parallelisation-friendly, customizable per elements
Pre-release
SUMMARY:
- upgraded waiting of commands, error messages, thread local configuration, etc. (see CHANGELOG for more details)
- it should be
- faster,
- more stable/less-flaky (with implicit waiting till no overlay-style pre-loaders)
- more friendly to parallelisation in context of configuration,
- more customizable on elements level (not just global)
- it should be
Migrating from 1.0.0-alpha03 guide
- upgrade and check your build
- refactor your custom conditions:
- if you have implemented your own custom conditions by extending e.g.
Condition<SeleneElement>
- you will get a compilation error – to fix it:
- change base class from
Condition<SeleneElement>
toDescribedCondition<SeleneElement>
- remove
public override string Explain()
and leavepublic override string ToString()
instead - if you use anywehere in your code an
Apply
method on condition of typeCondition<TEntity>
- you will get an obsolete warning
- refactor your code to use
Invoke
method, taking into account that- anytime Apply throws exception - Invoke also throws exception
- anytime Apply returns false - Invoke throws exception
- anytime Apply returns true - Invoke just passes (it's of void type)
- refactor your code to use
- you will get an obsolete warning
- change base class from
- you will get a compilation error – to fix it:
- if you have implemented your own custom conditions by extending e.g.
- refactor obsolete things, like:
Configuration.WebDriver
=>Configuration.Driver
S("#element").ShouldNot(Be.*)
toS("#element").Should(Be.Not.*)
S("#element").ShouldNot(yourCustomCondition)
toS("#element").Should(yourCustomCondition.Not)
- etc
- refactor your custom conditions:
- take into account, that some "internal" methods of 1.0.0-alpha05 were made public for easiser experimental testing in prod:),
but still considered as internal, that might change in future
such methods are named with_
prefix,
following kind of Python lang style of "still publically accessible private" methods:)
use such methods on your own risk, take into account that they might be marked as obsolete in future
yet, they will be eather renamed or made completely internal till stable 1.0 release;)
read CHANGELOG for more details.
Details
- added
Be.Not.*
andHave.No.*
as entry points to "negated conditions" .ShouldNot
is obsolete now, use.Should(Be.Not.*)
or.Should(Have.No.*)
instead- added
Condition#Not
property,Condition#Or(condition)
,Condition#And(condition)
- added condition-builder classes, yet marked as internal
Not<TEntity> : Condition<TEntity>
Or<TEntity> : Condition<TEntity>
And<TEntity> : Condition<TEntity>
- yet they might be renamed in future... to something like NotCondition, OrConditioin, AndCondition
- let's finalize the naming in #53
- added condition-builder classes, yet marked as internal
- added SeleneElement extensions
.JsScrollIntoView()
.JsClick(centerXOffset=0, centerYOffset=0)
- proper tests coverage is yet needed
- the same can be achieved through (can be handy when storing element in var)
element.With(clickByJs: true).Click()
.JsSetValue(value)
- the same can be achieved through
element.With(setValueByJs: true).SetValue(value)
- the same can be achieved through
.JsType(value)
- the same can be achieved through
element.With(typeByJs: true).Type(value)
- the same can be achieved through
- made Configuration.* ThreadLocal
- added SeleneElement methods:
WaitUntil(Condition)
– like Should, but returns false on failureMatching(Condition)
- the predicate, like WaitUntil but without waitingWith([driver], [timeout], [pollDuringWaits], [setValueByJs], [typeByJs], [clickByJs])
- to override corresponding selene setting from Configuration- usage:
element.With(timeout: 2.0)
- usage:
_With_(_SeleneSettings_)
option to fully disconnect element config from shared Configuration- underscores mean that method signature might change...
- usage:
element._With_(Configuration.New(timeout: 2.0))
- added SeleneCollection methods:
WaitUntil(Condition)
– like Should, but returns false on failureMatching(Condition)
- the predicate, like WaitUntil but without waitingWith([driver], [timeout], [pollDuringWaits], [setValueByJs], [typeByJs], [clickByJs])
- to override corresponding selene setting from Configuration_With_(_SeleneSettings_)
option to fully disconnect element config from shared Configuration- underscores mean that method signature might change...
- usage:
elements._With_(Configuration.New(timeout: 2.0))
- added SeleneDriver methods:
WaitUntil(Condition)
– like Should, but returns false on failureMatching(Condition)
- the predicate, like WaitUntil but without waitingWith([driver], [timeout], [pollDuringWaits], [setValueByJs], [typeByJs], [clickByJs])
- to override corresponding selene setting from Configuration_With_(_SeleneSettings_)
option to fully disconnect element config from shared Configuration- underscores mean that method signature might change...
- usage:
elements._With_(Configuration.New(timeout: 2.0))
- tuned selene elements representation in error messages
- now code like
SS(".parent").FilterBy(Be.Visible)[0].SS(".child").FindBy(Have.CssClass("special")).S("./following-sibling::*")
- renders to:
Browser.All(.parent).By(Visible)[0].All(.child).FirstBy(has CSS class 'special').Element(./following-sibling::*)
- now code like
- improved waiting (waits not just for visibility but till "being passed") at SeleneElement's:
- (... wait till visible and not overlapped)
- Click()
- Hover()
- DoubleClick()
- Submit()
- Clear()
- SetValue(keys)
- Type(keys)
- PressEnter()
- PressEscape()
- PressTab()
- (... wait till visible for all but
input[type=file]
)- SendKeys(keys)
- (... wait till visible and not overlapped)
- upgraded waiting to new engine in asserts (.Should(condition)) of
- SeleneElement
- SeleneCollection
- Deprecated (Marked as Obsolete)
Configuration.WebDriver
(useConfiguration.Driver
instead)- it also becomes a recommended wa
- to set driver:
Configuration.Driver = myDriverInstance
- over
Selene.SetWebDriver(myDriverInstance)
- that might be deprecated in future
- over
- also take into account that in frameworks like NUnit3,
when you tear down driver in OneTimeTearDown (that will be executed after all test methods)
ensure you do this by callingQuit
on your own instance likemyDriverInstance.Quit()
DON'T do it likeConfiguration.Driver.Quit()
orSelene.GetWebDriver().Quit()
cause this will lead in memory leaked driver, this is NUnit thing, not NSelene:)
(you still can do the latter in TearDown method that will be executed after each test method)
- to set driver:
- it also becomes a recommended wa
- potential breaking changes:
- Switched to System.TimeoutException in some waits (instead of WebDriverTimeoutException)