yashaka / NSelene

Consise API to Selenium for .Net (the port of Selene in python / Selenide in Java)
MIT License
68 stars 21 forks source link

extend Have.Attribute(name, value) to more cases #83

Closed yashaka closed 9 months ago

yashaka commented 3 years ago

TODO:

yashaka commented 3 years ago

consider not just "by contains" but also "starts with" and "ends with"... and even "matches to" (i.e. via regex)

davespoon commented 3 years ago

I'd like to do it, but my free time consists mainly of weekends =)

yashaka commented 3 years ago

Let's see)

First, we need to figure out naming for all cases)

Then implementation would be simple)

On Wed, May 12, 2021, 16:30 Grinevich Dmitriy @.***> wrote:

I'd like to do it, but my free time consists mainly of weekends =)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/yashaka/NSelene/issues/83#issuecomment-839773983, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAO6ZHWVKWB2IVIRDDUPQS3TNJ7HTANCNFSM43VHWS5A .

davespoon commented 3 years ago

Also i have doubts about different realization. As I understand, changing Attribute.Invoke() implementation is not good idea? Should we create some new conditions like Name: Condition<SeleneElement>?

davespoon commented 3 years ago

Also i have doubts about different realization. As I understand, changing Attribute.Invoke() implementation is not good idea? Should we create some new conditions like Name: Condition<SeleneElement>?

Or maybe better for Name to be inherited from Attribute

davespoon commented 1 year ago

Here is some of my thoughts: 1 create new condition:

public class AttributeExists : Condition<SeleneElement>
        {
            private static string _name;

            public AttributeExists(string name)
            {
                _name = name;
            }

            public override Condition<SeleneElement> WithValueStarting(string value)
            {
                return new StartingWithCondition(_name, value);
            }

            public override void Invoke(SeleneElement entity)
            {
                var webelement = entity.ActualWebElement;
                if (webelement.GetAttribute(_name) == null)
                {
                    throw new ConditionNotMatchedException(() =>
                        "Found element does not contain expected attribute "
                        + webelement.GetAttribute("outerHTML")
                    );
                }
            }
        }
    }
  1. Add new Condition StartingWithCondition(it could be Matching regex or anything else):
public class StartingWithCondition : Condition<SeleneElement>
        {
            private readonly string name;
            private readonly string value;

            public StartingWithCondition(string name, string value)
            {
                this.name = name;
                this.value = value;
            }

            public override void Invoke(SeleneElement entity)
            {
                var webelement = entity.ActualWebElement;
                var maybeActual = webelement.GetAttribute(this.name);

                if (maybeActual == null || !maybeActual.StartsWith(this.value))
                {
                    throw new ConditionNotMatchedException(() =>
                        (maybeActual == null
                            ? $"Actual {this.name}: Null (attribute is absent)\n"
                            : $"Actual {this.name}: «{maybeActual}»\n")
                        + $"Actual webelement: {webelement.GetAttribute("outerHTML")}"
                    );
                }
            }

Obvious problem here is having now new virtual method with no normal implementation inside Condition class:

public virtual Condition<SeleneElement> WithValueStarting(string value)
            {
                throw new NotImplementedException();
            }