<commit_before>Bumblebee
=========

Bumblebee is a layer on top of the Selenium browser automation framework. Using Bumblebee and the accompanying design paradigm allows for easy creation of page objects, even for dynamic web pages.

Bumblebee makes browser automation dead simple. Develop page objects quickly by modeling which parts of the page can be interacted with. Then, using Intellisense, we can check what elements/blocks are on the page and easily perform actions on them.

The basic idea behind Bumblebee is to break each page down into blocks and elements. Use the classes provided by bumblebee to model your site into page objects. Consume page objects by writing your automation code. If page objects are well designed, writing the automation code should take no effort.

Blocks
------

A block is an area on a web page. This could be an entire page, or a subset, like a tab menu, or a sidebar. Each block is represented by a class that extends *Block*. Blocks can contain child elements or child blocks. Each child is represented by a property in the parent block's class. Say we have some home page *HomePage*.

```C#
public class HomePage : Page
{
    public HomePage(Session session) : base(session)
    {
    }
    
    // Properties go here
}
```

Page here is a base type that is not provided by Bumblebee, but extends Block. It is the base block for this project. More on that later.

Elements
--------

An element is a user interface item. Examples include links, buttons, checkboxes, select boxes, etc. Each type of element is represented by an interface. For example IClickable represents both buttons and links (with a single method, "Click").

Each element on a page gets represented by a property. The most important part of the property is the return type. The type returned should be the interface of the element, for example *ISelectBox*. This is how the user (the person writing the automation test case) can interact with the element. 

The generic type parameter of the return type is where the scope returns to after the element is interacted with. For elements that generally do not change the page, the generic type is typically the type of the parent block (the block of which the element is a property). Suppose there is a select box on our home page for the user to choose their favorite color. We define the property like this:

<<<<<<< HEAD
```C#
public ISelectBox&lt;HomePage&gt; FavoriteColorSelectBox { ... }
```
=======
<code>Session.NavigateTo&lt;HomePage&gt;("http://www.google.com").SearchBar.EnterText("kittens").SearchButton.Click();</code>
>>>>>>> 16a6b15fcfa1c6f1989b37e1e2f00a34f93e3428

For elements that generally do change the state of the page, the type parameter is the type of the block that is led to. For example, say we have a link to an about page *AboutPage*.

```C#
public IClickable&lt;AboutPage&gt; AboutLink { ... }
```

Sometimes, however, performing an action could lead to several different places on the site. For example, say we have a "Log In" button. Clicking this button could lead to the profile page *ProfilePage* or stay on the home page with an invalid login message. Elements like this are deemed "conditional" and have seperate interfaces. We'd model the button like this:

```C#
public IConditionalClickable LogInButton { ... }
```

Notice there is no generic type parameter; we don't know where it will go so we cannot specify ahead of time.

To implement the property, we must return a concrete type. For most cases, each interface's corresponding implementation should suffice (*Clickable* for *IClickable*). We diverge from this pattern when a site contains custom UI elements (like jQuery select boxes and such). If the element on the page fits the interface, but is implemented differently, make a custom implementation and use that.

Element implementations take two parameters. The first is the parent block of the element, which it uses for scope. Just pass *this*, as we are calling from the parent block. The second is the selector for the element (a Selenium By object). Alternatively, you can pass the IWebElement representing the element, which is often useful.

Here are the properties above implemented fully:

```C#
public ISelectBox&lt;HomePage&gt; FavoriteColorSelectBox
{
    get { return new SelectBox<HomePage>(this, By.Id("favoriteColor")); }
}<commit_msg>Remove merge notes from README<commit_after>Bumblebee
=========

Bumblebee is a layer on top of the Selenium browser automation framework. Using Bumblebee and the accompanying design paradigm allows for easy creation of page objects, even for dynamic web pages.

Bumblebee makes browser automation dead simple. Develop page objects quickly by modeling which parts of the page can be interacted with. Then, using Intellisense, we can check what elements/blocks are on the page and easily perform actions on them.

The basic idea behind Bumblebee is to break each page down into blocks and elements. Use the classes provided by bumblebee to model your site into page objects. Consume page objects by writing your automation code. If page objects are well designed, writing the automation code should take no effort.

Blocks
------

A block is an area on a web page. This could be an entire page, or a subset, like a tab menu, or a sidebar. Each block is represented by a class that extends *Block*. Blocks can contain child elements or child blocks. Each child is represented by a property in the parent block's class. Say we have some home page *HomePage*.

```C#
public class HomePage : Page
{
    public HomePage(Session session) : base(session)
    {
    }
    
    // Properties go here
}
```

Page here is a base type that is not provided by Bumblebee, but extends Block. It is the base block for this project. More on that later.

Elements
--------

An element is a user interface item. Examples include links, buttons, checkboxes, select boxes, etc. Each type of element is represented by an interface. For example IClickable represents both buttons and links (with a single method, "Click").

Each element on a page gets represented by a property. The most important part of the property is the return type. The type returned should be the interface of the element, for example *ISelectBox*. This is how the user (the person writing the automation test case) can interact with the element. 

The generic type parameter of the return type is where the scope returns to after the element is interacted with. For elements that generally do not change the page, the generic type is typically the type of the parent block (the block of which the element is a property). Suppose there is a select box on our home page for the user to choose their favorite color. We define the property like this:

```C#
public ISelectBox&lt;HomePage&gt; FavoriteColorSelectBox { ... }
```

For elements that generally do change the state of the page, the type parameter is the type of the block that is led to. For example, say we have a link to an about page *AboutPage*.

```C#
public IClickable&lt;AboutPage&gt; AboutLink { ... }
```

Sometimes, however, performing an action could lead to several different places on the site. For example, say we have a "Log In" button. Clicking this button could lead to the profile page *ProfilePage* or stay on the home page with an invalid login message. Elements like this are deemed "conditional" and have seperate interfaces. We'd model the button like this:

```C#
public IConditionalClickable LogInButton { ... }
```

Notice there is no generic type parameter; we don't know where it will go so we cannot specify ahead of time.

To implement the property, we must return a concrete type. For most cases, each interface's corresponding implementation should suffice (*Clickable* for *IClickable*). We diverge from this pattern when a site contains custom UI elements (like jQuery select boxes and such). If the element on the page fits the interface, but is implemented differently, make a custom implementation and use that.

Element implementations take two parameters. The first is the parent block of the element, which it uses for scope. Just pass *this*, as we are calling from the parent block. The second is the selector for the element (a Selenium By object). Alternatively, you can pass the IWebElement representing the element, which is often useful.

Here are the properties above implemented fully:

```C#
public ISelectBox&lt;HomePage&gt; FavoriteColorSelectBox
{
    get { return new SelectBox<HomePage>(this, By.Id("favoriteColor")); }
}
{'fraction_non_alphanumeric': 0.05931905931905932, 'fraction_numerical': 0.002925002925002925, 'mean_word_length': 4.339163023110556, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6549774', 'n_tokens_mistral': 2110, 'n_tokens_neox': 2028, 'n_words': 1299}