4
\$\begingroup\$

I submitted this script as part of a interview process. It was rejected and no reasons were given. I'm wondering what parts of my script were unacceptable. The script works, and satisfies the question, but I must be doing things very wrong.

Use Selenium, Watir, Capybara, or similar to automate the following user workflow:

  • Send a message to Slack by entering text in the box at the bottom of the - - client
  • Your message will appear in the current channel.
  • When you hover over the message, you'll see a star.
  • Click the star.
  • There is a search field on the upper right.
  • Enter the string has:star in this field and submit it.
  • Verify that your message appears in the search results.
  • Click the star icon on the upper right.
  • Verify that your message appears in this list.
// Setup test conditions and global resources.
var webdriver = require('selenium-webdriver'),
    By = webdriver.By;
var driver = new webdriver.Builder()
    .forBrowser('chrome')
    .build();
var query = 'has:star';
var dataTs = -1;
var messageFoundInSearchResults = false;
var messageFoundInStarResults = false;
var errors = [];
var messageStarredTime = -1;

// Code used to login and navigate to a channel. Used to test this test. Commented out because exercise did not request
// this step.
/*
var generalUrl = 'https://yourproject.slack.com/messages/yourchannel/';
var email = '[email protected]';
var password = 'yourpassword';
driver.get(generalUrl);
driver.findElement(By.id('email')).sendKeys(email);
driver.findElement(By.id('password')).sendKeys(password);
driver.findElement(By.id('signin_btn')).click();
driver.wait(function() {
    "use strict";
    return driver.isElementPresent(webdriver.By.className('ts_icon_side_panel'));
});
*/

// Enter message
driver.findElements(By.id('message-input')).then(function(elems) {

    "use strict";
    var sentTime = -1;
    var checkTime = -1;
    var timeDiff = -1;
    var timeout = 5000;
    var message = new Date().getTime();
    var messageReceived = false;

    if (elems.length > 0) {

        driver.findElement(By.id('message-input')).sendKeys(message + webdriver.Key.RETURN);
        sentTime = new Date().getTime();

        // Wait for new message to appear within timeout time, then get data timestamp.
        (function checkMessageSent() {

            driver.sleep(1000);
            checkTime = new Date().getTime();
            timeDiff = checkTime - sentTime;

            // For each message on the page, compare the messages text with the sent text.
            driver.findElements(By.css('ts-message')).then(function(elems) {
                elems.forEach(function(msg) {
                    msg.getText().then(function(text) {

                        // If the message text contains the sent text, then the message has been identified and the
                        // timestamp id is stored.
                        if (text.indexOf(message) > -1) {
                            messageReceived = true;
                            msg.getAttribute('data-ts').then(function(ts) {
                                dataTs = ts;
                            });
                        }
                    });
                });
                if (messageReceived === false && timeDiff < timeout) {
                    checkMessageSent();
                } else if (messageReceived === false && timeDiff >= timeout) {
                    errors.push(Date() + ': Sent message not found.');
                }
            });
        }());
    } else {
        errors.push(Date() + ': Cannot find message-input');
    }
});

// Find message and click it's star using the timestamp id.
driver.findElements(By.css('ts-message')).then(function(elems) {

    "use strict";

    // For each message on page, compare timestamp id to find the correct message.
    elems.forEach(function(msg) {
        msg.getAttribute('data-ts').then(function(id) {
            if (id == dataTs) {

                // Hover over message
                driver.actions().mouseMove(msg).perform();

                // Find all star buttons for the message.
                driver.findElements(By.css('button[data-msg-id="' + dataTs + '"]')).then(function(btns) {

                    // Click the star button which is visible.
                    btns.forEach(function(btn) {
                        btn.isDisplayed().then(function(val) {
                            if (val === true) {
                                btn.click();

                                // Store the time the message was starred for use in the "has:star" search timeout.
                                messageStarredTime = new Date().getTime();
                            }
                        });
                    });
                    if (btns.length === 0) {
                        errors.push(Date() + ': Cannot find any stars');
                    }
                });
            }
        });
    });
    if (elems.length === 0) {
        errors.push(Date() + ': Cannot find any ts-message');
    }
});

// Execute search until message is found or timeout reached.
driver.findElements(By.id('search_terms')).then(function(elems) {

    "use strict";
    var searchTime = -1;
    var timeDiff = -1;
    var maxWaitTime = 30000;
    var searchSleepTime = 5000;
    var searchPending = true;

    if (elems.length > 0) {

        // Focus on search bar
        driver.findElement(By.id('search_terms')).click();

        // Enter search query and search with Return key.
        driver.findElement(By.id('search_terms')).sendKeys(query + webdriver.Key.RETURN);

        // Pause for search results to appear.
        driver.wait(function() {
            return driver.isElementPresent(webdriver.By.className('flex_content_scroller'));
        }, maxWaitTime);
    } else {
        errors.push(Date() + ': Cannot find search_terms');
    }

    // Check search results for message in recursive function.
    (function checkSearchResults() {

        // Get current time for timeout comparison.
        searchTime = new Date().getTime();
        timeDiff = searchTime - messageStarredTime;

        // Get all message results
        driver.findElements(By.className('search_message_result null_transform ')).then(function(msgs) {

            // Compare each id with the stored id.
            msgs.forEach(function(msg) {
                msg.getAttribute('data-ts').then(function(msgTs) {

                    // If the timestamp ID's match then the message is found.
                    if (msgTs == dataTs) {
                        messageFoundInSearchResults = true;
                    }
                });
            });

            // If message has not been found and timeout has not been reached re-execute search after delay
            if (messageFoundInSearchResults === false && timeDiff < maxWaitTime) {
                driver.sleep(searchSleepTime);
                driver.findElement(By.id('search_terms')).sendKeys(webdriver.Key.RETURN);
                checkSearchResults();
            }
        });
    }());

    // Wait for the last search to complete.
    driver.wait(function(){
        driver.isElementPresent(webdriver.By.id('search_spinner')).then(function(isPresent){
            searchPending = isPresent;
        });
        if (searchPending === false) {
            return true;
        }
    });
});


// Click star icon and wait for results to load
driver.findElements(By.id('stars_toggle')).then(function(elems) {

    "use strict";
    var checkTime = -1;
    var starClickTime = -1;
    var timeDiff = -1;
    var waitTime = 3000;

    if (elems.length > 0) {
        driver.findElement(By.id('stars_toggle')).click();
        starClickTime = new Date().getTime();

        // Wait for results to load by checking if any message items are present in the results list, with timeout.
        (function checkStarredResults() {
            checkTime = new Date().getTime();
            timeDiff = checkTime - starClickTime;
            driver.isElementPresent(webdriver.By.className('message feature_fix_files   standalone  for_star_display' +
                '   first       ')).then(function(result) {
                if (result === false && timeDiff < waitTime) {
                    checkStarredResults();
                }
            });
        }());
    } else {
        errors.push(Date() + ': Cannot find stars_toggle');
    }
});



// Check list for message
driver.findElements(By.className('message feature_fix_files   standalone  for_star_display   ' +
    'first       ')).then(function(elems) {

    "use strict";

    elems.forEach(function(elem) {
        elem.getAttribute('data-ts').then(function(elemTs) {

            // If the timestamp ID's match then the message is found.
            if (elemTs == dataTs) {
                messageFoundInStarResults = true;
                logErrors();
            }
        });
    });
    if (elems.length === 0) {
        errors.push(Date() + ': Cannot find any message feature_fix_files   standalone  for_star_display   first       ');
        logErrors();
    }
});

// Log and output test results.
var logErrors = function() {

    "use strict";

    // Log error if the message was not found in search results.
    if (messageFoundInSearchResults === false) {
        errors.push(Date() + ': Message not found in search results.');
    }

    // Log error if the message was not found in Star list.
    if (messageFoundInStarResults === false) {
        errors.push(Date() + ': Message not found in star results.');
    }

    // Output test result to console.
    if (errors.length > 0) {
        console.log('Test failed with ' + errors.length + ' errors:');
        errors.forEach(function(error) {
            console.log(error);
        });
    } else {
        console.log('Test passed with ' + errors.length + ' errors.');
    }
};

// Stop the test
driver.quit();
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't work with javascript but there are few statements which raise red flag for me -

driver.findElement/s(By.***

having a method to get element/s and not repeat the entire statement again and again makes it more comprehensible

driver.sleep(1000);

Instead of sleep use explicit wait

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.