Example #1
0
def test_categories(client: BotIntegrationClient):
    # Responses implement __eq__
    assert (client.send_command_await("categories")
            == client.send_message_await(captions.CATEGORIES))

    cat = client.send_command_await("categories", num_expected=1)
    social = cat.inline_keyboards[0].press_button_await(pattern=r'.*Social')
    ilkb = social.inline_keyboards[0]
    assert ilkb.num_buttons > 3
    share_btn = ilkb.find_button(r'Share')
    assert 'Social' in share_btn.switch_inline_query
Example #2
0
def test_create_group_abort(client: BotIntegrationClient):
    client.send_message(text="test_create_group_abort",
                        chat_id=config('BOT_NAME'))

    response = client.send_command_await("/create", num_expected=1)
    assert response.num_messages == 1
    assert response.full_text.startswith("Ok, send the name of the group")

    response = client.send_command_await("/cancel", num_expected=1)
    assert response.num_messages == 1
    assert response.full_text.startswith("Sure, what now?")
Example #3
0
def create_group_command(client: BotIntegrationClient,
                         generated_name: str = None):
    if not generated_name:
        generated_name = generate_name()

    client.send_command_await('/create', num_expected=1)
    response = client.send_message_await(generated_name)
    assert response.full_text.startswith('Saved'), \
        "Correctly saved responses start with 'Saved.'"

    return generated_name
def test_help(client: BotIntegrationClient):
    # Send /help and wait for one message
    res = client.send_command_await("/help", num_expected=1)

    # Make some assertions about the response
    assert not res.empty, "Bot did not respond to /help command"
    assert 'reliable and unbiased bot catalog' in res.full_text.lower()
    keyboard = res.inline_keyboards[0]
    assert len(keyboard.rows[0]) == 3  # 3 buttons in first row
    assert len(keyboard.rows[1]) == 1  # 1 button in second row

    # Click the inline button that says "Contributing"
    contributing = res.inline_keyboards[0].press_button_await(pattern=r'.*Contributing')
    assert not contributing.empty, 'Pressing "Contributing" button had no effect.'
    assert "to contribute to the botlist" in contributing.full_text.lower()

    # Click the inline button that says "Help"
    help_ = res.inline_keyboards[0].press_button_await(pattern=r'.*Help')
    assert not contributing.empty, 'Pressing "Help" button had no effect.'
    assert "first steps" in help_.full_text.lower()

    # Click the inline button that says "Examples"
    examples = res.inline_keyboards[0].press_button_await(pattern=r'.*Examples')
    assert not examples.empty, 'Pressing "Examples" button had no effect.'
    assert "examples for contributing to the botlist:" in examples.full_text.lower()
def test_commands(client: BotIntegrationClient):

    for c in client.command_list:
        print("Sending {} ({})".format(c.command, c.description))

        res = client.send_command_await(c.command)
        assert not res.empty
Example #6
0
def enter_group(client: BotIntegrationClient, name: str):
    response = client.send_command_await('/groups', num_expected=1)
    pattern = r'.*{} | .+ member(s)'.format(name)
    menu = response.inline_keyboards[0].press_button_await(pattern=pattern)

    assert not menu.empty, 'Pressing "group_name" button had no effect.'
    assert name.lower() in menu.full_text.lower()
    return menu
Example #7
0
def group_is_existing(client: BotIntegrationClient, group_name: str):
    response = client.send_command_await("/groups", num_expected=1)
    for row in response.inline_keyboards[0].rows:
        assert len(row) == 1, "Each row should be of length 1"
        if row[0].text.startswith(group_name):
            return True
    else:
        return False
Example #8
0
def client():
    # setup
    print('Initializing integration test client')

    c = BotIntegrationClient(bot_under_test=settings.BOT_UNDER_TEST,
                             max_wait_response=8,
                             min_wait_consecutive=1.5,
                             global_action_delay=1.5,
                             session_name=settings.TEST_USERBOT_SESSION,
                             api_id=settings.API_ID,
                             api_hash=settings.API_HASH,
                             phone_number=settings.TEST_USERBOT_PHONE)
    print("Starting client...")
    c.start()
    if c.peer_id in settings.MODERATORS:
        print("Restarting bot...")
        c.send_command_await("r", num_expected=2)  # restart bot
    # c.clear_chat()
    yield c
    # teardown
    c.stop()
def test_explore_button(client: BotIntegrationClient):
    res = client.send_command_await("/start", num_expected=3)
    btn = next(x for x in res.keyboard_buttons if 'explore' in x.lower())

    explore = client.send_message_await(btn)
    assert explore.num_messages == 1

    count = 10
    while "explored all the bots" not in explore.full_text:
        if count == 0:
            break  # ok
        explore = explore.inline_keyboards[0].press_button_await(
            pattern=r'.*🔄')  # emoji
        count -= 1
def test_help(client: BotIntegrationClient):
    res = client.send_command_await("/help", num_expected=1)
    assert 'reliable and unbiased bot catalog' in res.full_text.lower()
    kb = res[0].reply_markup.inline_keyboard
    assert len(kb[0]) == 3
    assert len(kb[1]) == 1

    contributing = res.inline_keyboards[0].press_button_await(
        pattern=r'.*Contributing')
    assert "to contribute to the botlist" in contributing.full_text.lower()

    help_ = res.inline_keyboards[0].press_button_await(pattern=r'.*Help')
    assert "first steps" in help_.full_text.lower()

    examples = res.inline_keyboards[0].press_button_await(
        pattern=r'.*Examples')
    assert "Examples for contributing to the BotList:" in examples.full_text
def test_new(client: BotIntegrationClient):
    uname = '@test__bot'
    try:
        try:
            b = Bot.get(username=uname)
            b.delete_instance()
        except Bot.DoesNotExist:
            pass

        res = client.send_command_await("new", [uname])
        if client.get_me().id in settings.MODERATORS:
            assert 'is currently pending' in res.full_text.lower()
            assert res.inline_keyboards[0].find_button(r'.*Accept.*')
        else:
            assert re.search('you submitted.*for approval', res.full_text, re.IGNORECASE)
    finally:
        Bot.delete().where(Bot.username == uname)
Example #12
0
def test_explore_button(client: BotIntegrationClient):
    # Send /start to bot and wait for 3 messages
    start = client.send_command_await("/start", num_expected=3)

    # Click the "Explore" keyboard button
    explore = start.reply_keyboard.press_button_await(pattern=r'.*Explore')

    assert not explore.empty, 'Pressing the "Explore" button had no effect.'
    assert explore.inline_keyboards, 'The "Explore" message had no inline keyboard.'

    # Click the "Explore" inline keyboard button 10 times or until it says that
    # all bots have been explored
    count = 10
    while "explored all the bots" not in explore.full_text:
        if count == 0:
            break  # ok

        # Pressing an inline button also makes the BotController listen for edit events.
        explore = explore.inline_keyboards[0].press_button_await(index=2)
        assert not explore.empty, 'Pressing the "Explore" button had no effect.'
        count -= 1
Example #13
0
def test_add_members_to_existing_group(client: BotIntegrationClient):
    client.send_message(text="test_add_members_to_existing_group",
                        chat_id=config('BOT_NAME'))

    group_name = create_group_command(client)
    group_name = enter_group(client, group_name)
    button = group_name.inline_keyboards[0].press_button_await(
        pattern=r'.*Add members', min_wait_consecutive=5)

    assert not button.empty, 'Pressing "Add members" button had no effect.'
    assert button.full_text.startswith(
        'Ok, send'), "Adding users' message has been changed."

    user_name = generate_name()
    response = client.send_message_await(user_name, num_expected=1)
    assert response.full_text.startswith("Added")

    response = client.send_command_await("/done", num_expected=2)
    assert response[0].text.startswith('Saved new members')

    members = response[1].text.split('\n')[3:]
    members = [item.split()[1] for item in members]
    assert user_name in members, "User hasn't been added"
def test_start(client: BotIntegrationClient):
    # Send /start and wait for 3 messages
    res = client.send_command_await("/start", num_expected=3)
    assert res.num_messages == 3
    assert res[0].sticker  # First message is a sticker
def test_start(client: BotIntegrationClient):
    res = client.send_command_await("/start", num_expected=3)
    assert res.num_messages == 3
    assert res[0].sticker
Example #16
0
    max_wait_response=8,  # Maximum timeout for bot responses
    min_wait_consecutive=2,  # Minimum time to wait for consecutive messages
    raise_no_response=
    True  # Raise `InvalidResponseError` when no response received
)

print("Starting...")
client.start()

print("Clearing chat to start with a blank screen...")
client.clear_chat()

print(
    "Send the /start command to the bot_under_test and 'await' exactly three messages..."
)
response = client.send_command_await("start", num_expected=3)

assert response.num_messages == 3
print("Three messages received.")
assert response.messages[0].sticker
print("First message is a sticker.")

print("Let's examine the buttons in the response...")
inline_keyboard = response.inline_keyboards[0]
assert len(inline_keyboard.rows[0]) == 3
print("There are three buttons in the first row.")

# We can also query and press the inline keyboard buttons:
print("Click the first button matching the pattern r'.*Examples'")
examples = response.inline_keyboards[0].press_button_await(
    pattern=r'.*Examples')
Example #17
0
def test_start(client: BotIntegrationClient):
    client.send_message(text="test_start", chat_id=config('BOT_NAME'))

    response = client.send_command_await("/start", num_expected=1)
    assert response.num_messages == 1
    assert response.full_text.startswith("Hello")
Example #18
0
#!/usr/bin/python3.6

import sys
from tgintegration import BotIntegrationClient

if len(sys.argv) !=2: 
    raise Exception("Need to pass bot name via cli args. Example: ./test.py @my_awesome_bot")

c = BotIntegrationClient(
        session_name='my_account',
        bot_under_test=sys.argv[1],
        max_wait_response=4,  # Wait a max of 4 seconds for responses, ...
        raise_no_response=False,  # ... then check for response.empty instead of raising
        min_wait_consecutive=2.0,  # Wait at least 2 seconds to collect more than one message
        global_action_delay=1.8,  # Space out all messages by 1.8 seconds
    )

c.start(False)

res = c.send_command_await("/start", num_expected=1)
if res.num_messages == 1:
    print("OK")
else:
    print("FAIL")
c.stop()
Example #19
0
class DinoParkGame:
    VALUE_PATTERN = re.compile(r'^.*?\s*(\w+): ([\d ]+).*$', re.MULTILINE)
    NUMBERS_ONLY_PATTERN = re.compile(r'\b(\d[\d ]+)\b')

    def __init__(self, session_name, log_level=logging.INFO):
        self.purchase_balance = None
        self.withdrawal_balance = None
        self.diamonds = None

        self.menu = None  # type: ReplyKeyboard
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.setLevel(log_level)

        self.client = BotIntegrationClient(session_name=session_name,
                                           bot_under_test='@DinoParkBot',
                                           max_wait_response=20,
                                           min_wait_consecutive=2.0,
                                           global_action_delay=1.0,
                                           config_file=os.path.join(
                                               examples_dir, 'config.ini'))
        self.client.start()

        self._update_keyboard()
        self.update_balance()

    def _update_keyboard(self):
        start = self.client.send_command_await("start")
        self.menu = start.reply_keyboard

    def _extract_values(self, text):
        groups = self.VALUE_PATTERN.findall(text)
        try:
            return {g[0].lower(): str_to_int(g[1]) for g in groups}
        except KeyError:
            return {}

    def update_balance(self):
        balance = self.menu.press_button_await(r'.*Balance')
        values = self._extract_values(balance.full_text)

        self.purchase_balance = values['purchases']
        self.withdrawal_balance = values['withdrawals']
        self.diamonds = values['storehouse']

        self.logger.debug(
            "Balance updated: +{} for purchases, +{} for withdrawals, +{} diamonds."
            .format(self.purchase_balance, self.withdrawal_balance,
                    self.diamonds))

    def collect_diamonds(self):
        farm = self.menu.press_button_await(".*Farm")
        collected = farm.inline_keyboards[0].press_button_await(
            ".*Collect diamonds")

        num_collected = self._extract_values(collected.full_text).get(
            'collected', 0)
        self.diamonds += num_collected
        self.logger.info("{} diamonds collected.".format(
            num_collected if num_collected > 0 else 'No'))

    def sell_diamonds(self):
        market = self.menu.press_button_await(r'.*Marketplace')
        if not market.inline_keyboards:
            self.logger.debug("No selling available at the moment.")
            return
        sold_msg = market.inline_keyboards[0].press_button_await(
            r'Sell diamonds.*')

        values = self.VALUE_PATTERN.findall(sold_msg.full_text)
        sold = str_to_int(values[0][1])
        plus_purchase = str_to_int(values[1][1])
        plus_withdrawal = str_to_int(values[2][1])

        self.diamonds -= sold
        self.purchase_balance += plus_purchase
        self.withdrawal_balance += plus_withdrawal

        self.logger.info(
            "{} diamonds sold, +{} to purchase balance, +{} to withdrawal balance."
            .format(sold, plus_purchase, plus_withdrawal))

    def buy_dinosaurs(self):
        """
        Buy the best affordable dinosaurs
        """
        dinos = self.menu.press_button_await(r'.*Dinosaurs').inline_keyboards[
            0].press_button_await(r'.*Buy dinosaurs')

        # Build up a list of cost per dino
        dino_cost_sequence = []
        for msg in dinos.messages:
            # "Worth" in the message has no colon (:) before the number, therefore we use a numbers
            # only pattern
            values = self.NUMBERS_ONLY_PATTERN.findall(msg.caption)
            cost = str_to_int(values[0])
            dino_cost_sequence.append(cost)

        while True:
            try:
                can_afford_id = next(
                    x[0] for x in reversed(list(enumerate(dino_cost_sequence)))
                    if x[1] <= self.purchase_balance)
            except StopIteration:
                self.logger.debug("Can't afford any dinosaurs.")
                # Can not afford any
                break

            bought = dinos.inline_keyboards[can_afford_id].press_button_await(
                r'.*Buy')
            self.logger.info("Bought dinosaur: " + bought.full_text)

    def play_lucky_number(self):
        lucky_number = self.menu.press_button_await(
            r'.*Games').reply_keyboard.press_button_await(r'.*Lucky number')

        bet = lucky_number.reply_keyboard.press_button_await(
            r'.*Place your bet')

        if 'only place one bet per' in bet.full_text.lower():
            self.logger.debug("Already betted in this round")

            # Clean up
            self.client.delete_messages(
                self.client.peer_id,
                [bet.messages[0].message_id, bet.action_result.message_id])
            return
        self.client.send_message_await(str(random.randint(1, 30)))
        self.logger.debug("Bet placed.")
def test_commands(client: BotIntegrationClient):
    # The BotController automatically loads the available commands and we test them all here
    for c in client.command_list:
        res = client.send_command_await(c.command)
        assert not res.empty, "Bot did not respond to command /{}.".format(
            c.command)