/**************************************************************************** * Copyright 2008-2011 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Initial Contributors: * Håkan Råberg * Manish Chakravarty * Pavan K S ***************************************************************************/ package com.thoughtworks.krypton.driver.web.browser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.LocationEvent; import org.eclipse.swt.browser.LocationListener; import org.eclipse.swt.browser.TitleEvent; import org.eclipse.swt.browser.TitleListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public enum BrowserFamily { MOZILLA { public Browser create(Composite composite) { return new Browser(composite, SWT.MOZILLA); } void init(BrowserSession session) { configureXULRunnerUsingAboutConfig(session); // loadAboutBlank(session); } private void configureXULRunnerUsingAboutConfig(BrowserSession session) { session.getBrowser().setUrl("about:config"); session.pumpEvents(); waitForAboutConfigToInitialize(session); // setStringPreference(session, "general.useragent.extra.firefox", // "Gecko/2008070206 Firefox/3.0.1"); // setStringPreference(session, "general.useragent.extra.firefox", // "Firefox/2.0.0.13"); setBooleanPreference(session, "security.warn_entering_secure", false); setBooleanPreference(session, "security.warn_entering_weak", false); setBooleanPreference(session, "security.warn_leaving_secure", false); setBooleanPreference(session, "security.warn_submit_insecure", false); setBooleanPreference(session, "security.warn_viewing_mixed", false); } private void waitForAboutConfigToInitialize(BrowserSession session) { long timeout = System.currentTimeMillis() + 4000; boolean configLoaded = false; while (!configLoaded) { session.pumpEvents(); try { session.evaluate("gPrefBranch"); configLoaded = true; } catch (JavascriptException e) { if (!referenceError("gPrefBranch").equals(e.getMessage())) { throw e; } if (System.currentTimeMillis() >= timeout) { throw new IllegalStateException("Could not load about:config properly"); } try { Thread.sleep(20); } catch (InterruptedException ignore) { } } } } private void setPreference(BrowserSession session, String type, String key, Object value) { Object javaScriptValue = value instanceof String ? "'" + value + "'" : value; session.evaluate("gPrefBranch.set" + type + "Pref('" + key + "', " + javaScriptValue + ")"); if (!value.toString().equals(session.evaluate("gPrefBranch.get" + type + "Pref('" + key + "')"))) { throw new IllegalStateException("Failed to change preference " + key + " to " + value); } } // private void setStringPreference(BrowserSession session, String key, // String value) { // setPreference(session, "Char", key, value); // } private void setBooleanPreference(BrowserSession session, String key, boolean value) { setPreference(session, "Bool", key, value); } public String referenceError(String reference) { return "ReferenceError: " + reference + " is not defined"; } }, IE { public Browser create(Composite composite) { if (isSupported()) { return new Browser(composite, SWT.NONE); } throw new IllegalStateException("Cannot create Internet Explorer on platform: " + SWT.getPlatform()); } public boolean isSupported() { String platform = SWT.getPlatform(); return "win32".equals(platform); } public String referenceError(String reference) { return "[object Error]"; } public String newXmlHttpRequestCode() { return "new ActiveXObject('Microsoft.XMLHTTP')"; } }, SAFARI { public Browser create(Composite composite) { if (isSupported()) { return new Browser(composite, SWT.NONE); } throw new IllegalStateException("Cannot create Safari on platform: " + SWT.getPlatform()); } public boolean isSupported() { String platform = SWT.getPlatform(); return "carbon".equals(platform) || "cocoa".equals(platform); } public String referenceError(String reference) { return "ReferenceError: Can't find variable: " + reference; } }, INTERACTIVE { BrowserFamily actual; public Browser create(Composite composite) { if (actual == null) { askUser(); } return actual.create(composite); } private void askUser() { final Shell shell = new Shell(SWT.TITLE | SWT.APPLICATION_MODAL); shell.setLayout(new FillLayout()); shell.setText("Choose Browser"); Button mozilla = new Button(shell, SWT.NONE); mozilla.setText("Mozilla"); mozilla.setEnabled(MOZILLA.isSupported()); Button ie = new Button(shell, SWT.NONE); ie.setText("IE"); ie.setEnabled(IE.isSupported()); Button safari = new Button(shell, SWT.NONE); safari.setText("Safari"); safari.setEnabled(SAFARI.isSupported()); SelectionListener listener = new SelectionListener() { public void widgetSelected(SelectionEvent e) { System.setProperty(SYSTEM_PROPERTY, ((Button) e.getSource()).getText()); actual = BrowserFamily.fromSystemProperty(); shell.close(); shell.dispose(); } public void widgetDefaultSelected(SelectionEvent e) { } }; mozilla.addSelectionListener(listener); ie.addSelectionListener(listener); safari.addSelectionListener(listener); shell.pack(); shell.open(); Display display = shell.getDisplay(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } public String referenceError(String reference) { return actual.referenceError(reference); } }; public static final String SYSTEM_PROPERTY = "twist.driver.web.browser"; Logger log = LoggerFactory.getLogger(getClass()); // static { // java.util.logging.Logger.getLogger("").setLevel(java.util.logging.Level.FINEST); // java.util.logging.Logger.getLogger("").getHandlers()[0].setLevel(java.util.logging.Level.FINEST); // } public BrowserSession create() { final Shell shell = new Shell(); GridLayout layout = new GridLayout(); shell.setLayout(layout); shell.setSize(1024, 768); shell.setLocation(0, 0); Browser.clearSessions(); log.debug("Creating browser: {}", name()); Browser browser = create(shell); layoutBrowser(browser); BrowserSession session = new SWTBrowserSession(browser, this); init(session); browser.setUrl("about:blank"); session.pumpEvents(); Text location = addLocationBar(shell); Label userAgent = addUserAgentLabel(shell); addListeners(shell, location, browser); String userAgentString = session.evaluate("navigator.userAgent"); userAgent.setText(userAgentString); log.info("Initialized BrowserSession using {}", userAgentString); return session; } private void addListeners(final Shell shell, final Text location, final Browser browser) { browser.addLocationListener(new LocationListener() { public void changed(LocationEvent event) { if (event.top) { location.setText(event.location); } } public void changing(LocationEvent event) { } }); browser.addTitleListener(new TitleListener() { public void changed(TitleEvent event) { shell.setText(name() + " - " + event.title); } }); } private Label addUserAgentLabel(Shell shell) { Label userAgent = new Label(shell, SWT.CENTER); GridData data = new GridData(); data.horizontalAlignment = GridData.FILL; data.grabExcessHorizontalSpace = true; userAgent.setLayoutData(data); return userAgent; } private void layoutBrowser(Browser browser) { GridData data = new GridData(); data.horizontalAlignment = GridData.FILL; data.verticalAlignment = GridData.FILL; data.grabExcessHorizontalSpace = true; data.grabExcessVerticalSpace = true; browser.setLayoutData(data); } private Text addLocationBar(final Shell shell) { Text location = new Text(shell, SWT.BORDER); location.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); GridData data = new GridData(); data.horizontalAlignment = GridData.FILL; data.grabExcessHorizontalSpace = true; location.setLayoutData(data); return location; } void init(BrowserSession session) { } abstract Browser create(Composite composite); public abstract String referenceError(String reference); public boolean isSupported() { return true; } public static BrowserFamily fromSystemProperty() { return BrowserFamily.valueOf(System.getProperty(SYSTEM_PROPERTY, "safari").toUpperCase()); } public String newXmlHttpRequestCode() { return "new XMLHttpRequest()"; } }