Adding iCal Events from School Calendar URL in Python using Playwright

57 Views Asked by At

I am currently working on a Python script using Playwright to automate the process of adding an iCal link to Google Calendar. The script successfully navigates through the authentication process, entering the login credentials, but encounters issues when attempting to input a URL on the Google Calendar 'Add by URL' page. It must be in headless = True

from playwright.sync_api import sync_playwright
import time
from playwright.sync_api import Page

with sync_playwright() as playwright:
    browser = playwright.chromium.launch(headless=True, slow_mo=5000)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://accounts.google.com/v3/signin/identifier?dsh=S1611624178:1665765818620%20318&continue=https://calendar.google.com/calendar/r&followup=https://calendar.google.com/calendar/r&osid=1&passive=1209600&service=cl&flowName=GlifWebSignIn&flowEntry=ServiceLogin&ifkv=AQDHYWrL2lk0_Bcr1n1Y-f-i1sNZRKJK8CNisliX9rpozkqKhY2Jby8gsVZ_wDz_oHqiWmN6uZ6s6g&ec=wgc-calendar-globalnav-signin")
    userLogin = "username "
    userPass = "password"
    page.fill('input[type="email"]', userLogin)
    page.wait_for_selector('#identifierNext >> button', state="visible")
    page.wait_for_timeout(2000)  

    page.click('#identifierNext >> button')
    page.evaluate('''() => {
        const passwordInput = document.querySelector('input[type="password"]');
        passwordInput.style.display = 'inline';  // or 'block' or 'inline-block'
    }''')
    password_input = page.wait_for_selector('input[type="password"]', state="visible")
    password_input.fill(userPass)
    page.click('button >> nth=1')
    page.goto('https://calendar.google.com/calendar/u/0/r/settings/addbyurl')
    url_to_inject = 'https://brightspace.uri.edu/d2l/le/calendar/feed/user/feed.ics?token=althvrqormrwijfhdbe8'

    page.evaluate('''(url) => {
        const inputField = document.querySelector('input[jsname="YPqjbf"]');
        if (inputField) {
            // Click on the input field
            inputField.click();
            inputField.focus();

            inputField.click();
            // Set the value
            inputField.value = url;
        }
    }''', url_to_inject)
    # Check if the attribute is set on the input field
    attribute_value = page.evaluate('(url) => document.querySelector(\'input[jsname="YPqjbf"]\').getAttribute(\'data-injected\')', url_to_inject)

    if attribute_value == 'true':
        print("Script injection successful!")
    else:
        print("Script injection failed!") 

error I get:

playwright._impl._api_types.Error: TypeError: Cannot read properties of null (reading 'style')
    at eval (eval at evaluate (:208:30), <anonymous>:3:23)
    at UtilityScript.evaluate (<anonymous>:215:19)
    at UtilityScript.<anonymous> (<anonymous>:1:44)

HTML snippet of that input field:

<input type="text" value="" id="c67" jsname="YPqjbf" class="VfPpkd-fmcmS-wGMbrd " jsaction="focus:AHmuwe;blur:O22p3e;input:YPqjbf; mousedown:UX7yZ; mouseup:lbsD7e; pointerdown:QJflP; pointerup:HxTfMe; touchstart:p6p2H; touchend:yfqBxc;" aria-controls="c68" aria-describedby="c68" aria-labelledby="c64" maxlength="1024" autocomplete="off">

I have tried alot of ways and I understand its dynamic I was expecting it to input it and then I can get the embedded code after It does all the other actions:

#Checkbox after url input
 # page.evaluate('''(selector) => {
    # const checkbox = document.querySelector(selector);
    # if (checkbox) {
    #     checkbox.checked = true;
    #     checkbox.dispatchEvent(new Event('change'));
    # }
    # }''', 'input[jsname="YPqjbf"][type="checkbox"]')
#Add button clicked
    # page.evaluate('''(selector) => {
    # const button = document.querySelector(selector);
    # if (button) {
    #     button.click();
    # }
    # }''', 'button[jsname="V67aGc"]')

    # page.get_by_text("All Courses - University of Rhode Island").click()
    # page.get_by_role("treeitem", name="Integrate calendar").click()
    
    
    
    
    #embedded code link
    # dynamic_selector = '[jsname="YPqjbf"]'
    # page.wait_for_selector(dynamic_selector, timeout=20000)
    # embed_code_element = page.locator(dynamic_selector).nth(4)
    # print(embed_code_element)
    # element_html = str(embed_code_element.input_value())
    # page.screenshot(path='screenshot.png')
    # print(element_html)
0

There are 0 best solutions below