There are no Grammarly applications that could deliver integration with at least command-line. So let's make selenium automation that will paste text into Grammarly documents!

S0-E16/E30 :)

Grammarly Integration

For now [mid-February 2018] Grammarly does not give their users API that you could use in integrations with some blogging engines, but instead, you can use their Android/iOS spelling keyboard on your mobile or use Web-browser.

There are integrations for Chrome as a plugin, Firefox addon and native in Windows and MacOS.

Since I'm a more into Linux - There is no real alternative than using their web-app.

Yes, they are excellent and I still use them. But for now, I don't have mobile-integration for my blogging experience, as Pelican is a static-site generator and I store files on my computer. I'm planning to make some automations, and this post is one of them :)

The best thing for now that I still do is manually copy-paste the actual text of blog-post and put it in Google-Keep and then use Grammarly Firefox Plugin. That seems a bit silly and not as handy as an Automation that could do that for me.

Selenium automation for Grammarly

So I said to myself - why not create Selenium automation that will at least put actual text of blog-post into Grammarly Document?

Grammarly-Selenium-Automation project init.

First, let's create a repository on GitHub called grammarly-selenium-automation. Then Let's make git-repo with:

mkdir grammarly-selenium-automation
cd grammarly-selenium-automation
git init .
git commit --allow-empty -m "Init"
wget https://www.gitignore.io/api/vim%2Cpython -O .gitignore
git add .gitignore
git commit -m "Adds gitignore"
git remote add origin git@github.com:anselmos/grammarly-selenium-automation.git
git push -u origin master

And now we have our repository available on github.

Now let's make actual selenium login-automation.

Grammarly Selenium login script.

For this script, I'll use one of my previous blog posts about making selenium-automation.

BTW - I've ofcourse forgot about making a virtualenv for using selenium :

cd grammarly-selenium-automation && virtualenv .env && source .env/bin/activate && pip install selenium && pip freeze > requirements.txt
git add requirements.txt
git commit -m "Adds pip requirements.txt"
git push origin HEAD:master

And now the script: login.py script

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from grammarly_page import GrammarlyLogin
import time

class GrammarlyGeneralTest(unittest.TestCase):

    def setUp(self):
        # for dev I'll use only visible browser instead of no-gui one.
        # but for production, it will use the no-gui one.
        # self.driver = webdriver.Firefox()
        # TODO uncomment it when finished coding.
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4444/wd/hub',
            desired_capabilities={'browserName': 'firefox', 'javascriptEnabled': True}
        )


    def test_grammarly_in_title(self):
        page_login = GrammarlyLogin(self.driver)
        self.driver.get(page_login.uri)
        assert "Grammarly" in self.driver.title

    def test_login(self):
        page_login = GrammarlyLogin(self.driver)
        page_login.make_login('za2217279@mvrht.net', 'test123')
        time.sleep(2)
        assert self.driver.current_url == "https://app.grammarly.com/"

    def tearDown(self):
        self.driver.close()

if __name__ == "__main__":
    unittest.main()

and the grammarly_page.py :

from page_objects import PageObject, PageElement

class GrammarlyLogin(PageObject):
    username = PageElement(css='input[type="email"]')
    password = PageElement(css='input[type="password"]')
    login = PageElement(css='button[type="submit"]')
    uri = 'https://www.grammarly.com'
    signin_uri = '/signin'

    def make_login(self, username, password):
        self.get(self.uri + self.signin_uri)
        self.username = username
        self.password = password
        self.login.click()

You can find it also at this repo tag: login-page-done

Grammarly Selenium adds new file:

Now ! :) to the fun-part :) Let's make a new document in Grammarly and push it to the grammarly with copying data.

While I was working on making new doc script, I've decided to change naming of the login.py file into tests.py - because I thought it will be more meaningful - since that's what it contains :)

Moving on :

Within grammarly_page.py I've added this:

class GrammarlyNewDocument(PageObject):
    uri = 'https://app.grammarly.com/'
    new_document = PageElement(css='div[role="button"]')

    def make_new_document(self, name=None):
        self.get(self.uri)
        self.new_document.click()
        time.sleep(2)


class GrammarlyDocument(PageObject):

    title = PageElement(css='input[type="text"]')
    text = PageElement(id_='textarea')

    def put_title(self, title):
        self.title = title

    def put_text(self, text):
        self.text = text

And on the tests.py I've added this:

    def test_make_new_doc(self):
        page_login = GrammarlyLogin(self.driver)
        page_login.make_login('za2217279@mvrht.net', 'test123')
        page_new_doc = GrammarlyNewDocument(self.driver)
        page_new_doc.make_new_document("TEST")
        assert "https://app.grammarly.com/docs/" in self.driver.current_url

    def test_change_title_on_doc(self):
        page_login = GrammarlyLogin(self.driver)
        page_login.make_login('za2217279@mvrht.net', 'test123')
        page_new_doc = GrammarlyNewDocument(self.driver)
        page_new_doc.make_new_document("")
        page_doc = GrammarlyDocument(self.driver)
        self.assert_title(page_doc)

    def test_change_text_on_doc(self):
        page_login = GrammarlyLogin(self.driver)
        page_login.make_login('za2217279@mvrht.net', 'test123')
        page_new_doc = GrammarlyNewDocument(self.driver)
        page_new_doc.make_new_document("")
        page_doc = GrammarlyDocument(self.driver)
        self.assert_text(page_doc)

    def test_change_title_and_text_on_doc(self):
        page_login = GrammarlyLogin(self.driver)
        page_login.make_login('za2217279@mvrht.net', 'test123')
        page_new_doc = GrammarlyNewDocument(self.driver)
        page_new_doc.make_new_document("")
        page_doc = GrammarlyDocument(self.driver)
        self.assert_title(page_doc)
        self.assert_text(page_doc)

    def assert_title(self, page_doc):
        title_expected = "NewTestTitle"
        page_doc.put_title(title_expected)
        time.sleep(2)
        actual_doc = GrammarlyDocument(self.driver)
        self.assertEquals(page_doc.title, actual_doc.title)

    def assert_text(self, page_doc):
        text_expected = "A very bad text that are have some issues and Grammarly Should find problems with it"
        page_doc.put_text(text_expected)
        time.sleep(2)
        actual_doc = GrammarlyDocument(self.driver)
        self.assertEquals(page_doc.text, actual_doc.text)

You can check the whole project in this state at tag: doc-title-and-text

Pelican plugin for Grammarly

That's just a POC for making Grammarly and Selenium Automation. In part2 I'll try to make integration with the pelican engine.

This time I'll focus my attention on gathering as much as I can from the Grammarly document Checker. :)

Acknowledgements

Grammarly Alternatives: - TextGears - this one has an API that you could use. ( and payment for amount of requests/data sent)

Thanks!

That's it :) Comment, share or don't :)

If you have any suggestions what I should blog about in the next articles - please give me a hint :)

See you tomorrow! Cheers!



Comments

comments powered by Disqus