diff --git a/build/mobile/robocop/FennecMochitestAssert.java.in b/build/mobile/robocop/FennecMochitestAssert.java.in index 9576aabfe2e..9f754119936 100644 --- a/build/mobile/robocop/FennecMochitestAssert.java.in +++ b/build/mobile/robocop/FennecMochitestAssert.java.in @@ -63,12 +63,12 @@ public class FennecMochitestAssert implements Assert { /** Write information to a logfile and logcat */ public void dumpLog(String message) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message); } /** Write information to a logfile and logcat */ public void dumpLog(String message, Throwable t) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message, t); } /** Set the filename used for dumpLog. */ diff --git a/build/mobile/robocop/FennecNativeActions.java.in b/build/mobile/robocop/FennecNativeActions.java.in index d96b723b92d..a294545037b 100644 --- a/build/mobile/robocop/FennecNativeActions.java.in +++ b/build/mobile/robocop/FennecNativeActions.java.in @@ -63,6 +63,8 @@ import org.json.*; import com.jayway.android.robotium.solo.Solo; +import static @ANDROID_PACKAGE_NAME@.FennecNativeDriver.LogLevel; + public class FennecNativeActions implements Actions { private Solo mSolo; private Instrumentation mInstr; @@ -104,15 +106,15 @@ public class FennecNativeActions implements Actions { Class gslc = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient"); mDrawListener = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient$DrawListener"); mSetDrawListener = gslc.getDeclaredMethod("setDrawListener", mDrawListener); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } + } catch (ClassNotFoundException e) { + FennecNativeDriver.log(LogLevel.ERROR, e); + } catch (SecurityException e) { + FennecNativeDriver.log(LogLevel.ERROR, e); + } catch (NoSuchMethodException e) { + FennecNativeDriver.log(LogLevel.ERROR, e); + } catch (IllegalArgumentException e) { + FennecNativeDriver.log(LogLevel.ERROR, e); + } } class wakeInvocationHandler implements InvocationHandler { @@ -137,7 +139,7 @@ public class FennecNativeActions implements Actions { if(methodName.equals("hashCode")) { return 314; } - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, "Waking up on "+methodName); mEventExpecter.notifyOfEvent(); return null; @@ -159,11 +161,11 @@ public class FennecNativeActions implements Actions { try { this.wait(); } catch (InterruptedException ie) { - ie.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, ie); break; } } - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, "unblocked on expecter for " + mGeckoEvent); } @@ -175,11 +177,11 @@ public class FennecNativeActions implements Actions { try { mUnregisterGEL.invoke(null, mRegistrationParams); } catch (IllegalAccessException e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, "received event " + mGeckoEvent); synchronized (this) { mEventReceived = true; @@ -189,7 +191,7 @@ public class FennecNativeActions implements Actions { } public EventExpecter expectGeckoEvent(String geckoEvent) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, "waiting for "+geckoEvent); try { Class [] interfaces = new Class[1]; @@ -205,9 +207,9 @@ public class FennecNativeActions implements Actions { return expecter; } catch (IllegalAccessException e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } return null; } @@ -222,7 +224,7 @@ public class FennecNativeActions implements Actions { public Object invoke(Object proxy, Method method, Object[] args) { String methodName = method.getName(); if ("drawFinished".equals(methodName)) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, "Received drawFinished notification"); mPaintExpecter.notifyOfEvent(); } else if ("toString".equals(methodName)) { @@ -257,14 +259,14 @@ public class FennecNativeActions implements Actions { try { this.wait(); } catch (InterruptedException ie) { - ie.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, ie); break; } } try { mSetDrawListener.invoke(mLayerClient, (Object)null); } catch (Exception e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } } @@ -281,7 +283,7 @@ public class FennecNativeActions implements Actions { try { this.wait(); } catch (InterruptedException ie) { - ie.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, ie); break; } } @@ -291,7 +293,7 @@ public class FennecNativeActions implements Actions { try { this.wait(millis); } catch (InterruptedException ie) { - ie.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, ie); break; } long endTime = SystemClock.uptimeMillis(); @@ -305,7 +307,7 @@ public class FennecNativeActions implements Actions { try { mSetDrawListener.invoke(mLayerClient, (Object)null); } catch (Exception e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); } } } @@ -314,7 +316,7 @@ public class FennecNativeActions implements Actions { try { return new PaintExpecter(); } catch (Exception e) { - e.printStackTrace(); + FennecNativeDriver.log(LogLevel.ERROR, e); return null; } } diff --git a/build/mobile/robocop/FennecNativeDriver.java.in b/build/mobile/robocop/FennecNativeDriver.java.in index deda41919a7..7a1fed619cb 100644 --- a/build/mobile/robocop/FennecNativeDriver.java.in +++ b/build/mobile/robocop/FennecNativeDriver.java.in @@ -78,7 +78,7 @@ public class FennecNativeDriver implements Driver { private Solo mSolo; private static String mLogFile = null; - private static LogLevel mLogLevel = LogLevel.LOG_LEVEL_INFO; + private static LogLevel mLogLevel = LogLevel.INFO; // Objects for reflexive access of fennec classes. private ClassLoader mClassLoader; @@ -95,10 +95,10 @@ public class FennecNativeDriver implements Driver { private Method _getPixels; public enum LogLevel { - LOG_LEVEL_DEBUG(1), - LOG_LEVEL_INFO(2), - LOG_LEVEL_WARN(3), - LOG_LEVEL_ERROR(4); + DEBUG(1), + INFO(2), + WARN(3), + ERROR(4); private int mValue; LogLevel(int value) { @@ -142,15 +142,15 @@ public class FennecNativeDriver implements Driver { Class layerView = mClassLoader.loadClass("org.mozilla.gecko.gfx.LayerView"); _getPixels = layerView.getDeclaredMethod("getPixels"); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } + } catch (ClassNotFoundException e) { + log(LogLevel.ERROR, e); + } catch (SecurityException e) { + log(LogLevel.ERROR, e); + } catch (NoSuchMethodException e) { + log(LogLevel.ERROR, e); + } catch (IllegalArgumentException e) { + log(LogLevel.ERROR, e); + } } //Information on the location of the Gecko Frame. @@ -218,9 +218,9 @@ public class FennecNativeDriver implements Driver { Object [] params = null; _startFrameRecording.invoke(null, params); } catch (IllegalAccessException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } } @@ -239,9 +239,9 @@ public class FennecNativeDriver implements Driver { } return numDelays; } catch (IllegalAccessException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } return 0; @@ -252,9 +252,9 @@ public class FennecNativeDriver implements Driver { Object [] params = null; _startCheckerboardRecording.invoke(null, params); } catch (IllegalAccessException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } } @@ -271,9 +271,9 @@ public class FennecNativeDriver implements Driver { } return completeness / (float)checkerboard.size(); } catch (IllegalAccessException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } return 0.0f; @@ -288,7 +288,7 @@ public class FennecNativeDriver implements Driver { } } } catch (ClassNotFoundException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } return null; } @@ -302,7 +302,7 @@ public class FennecNativeDriver implements Driver { try { pixelBuffer = (IntBuffer)_getPixels.invoke(view); } catch (Exception e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); return null; } @@ -341,7 +341,7 @@ public class FennecNativeDriver implements Driver { fos.close(); } } catch (IOException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); throw new RoboCopException("exception closing pixel writer on file: " + mapFile); } } @@ -366,7 +366,7 @@ public class FennecNativeDriver implements Driver { } } catch( Throwable e) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_WARN, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN, "WARNING: ScrollReceived, but read wrong!"); } return null; @@ -393,9 +393,9 @@ public class FennecNativeDriver implements Driver { finalParams[1] = Proxy.newProxyInstance(mClassLoader, interfaces, new scrollHandler()); mRegisterGEL.invoke(null, finalParams); } catch (IllegalAccessException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } catch (InvocationTargetException e) { - e.printStackTrace(); + log(LogLevel.ERROR, e); } } @@ -416,8 +416,8 @@ public class FennecNativeDriver implements Driver { text.append(line); text.append('\n'); } - } catch(IOException e) { - e.printStackTrace(); + } catch (IOException e) { + log(LogLevel.ERROR, e); } finally { try { br.close(); @@ -493,13 +493,13 @@ public class FennecNativeDriver implements Driver { } } - if (level == LogLevel.LOG_LEVEL_INFO) { + if (level == LogLevel.INFO) { Log.i("Robocop", message, t); - } else if (level == LogLevel.LOG_LEVEL_DEBUG) { + } else if (level == LogLevel.DEBUG) { Log.d("Robocop", message, t); - } else if (level == LogLevel.LOG_LEVEL_WARN) { + } else if (level == LogLevel.WARN) { Log.w("Robocop", message, t); - } else if (level == LogLevel.LOG_LEVEL_ERROR) { + } else if (level == LogLevel.ERROR) { Log.e("Robocop", message, t); } } diff --git a/build/mobile/robocop/FennecNativeElement.java.in b/build/mobile/robocop/FennecNativeElement.java.in index 0785a0de2bd..7b5dc8495b5 100644 --- a/build/mobile/robocop/FennecNativeElement.java.in +++ b/build/mobile/robocop/FennecNativeElement.java.in @@ -76,7 +76,7 @@ public class FennecNativeElement implements Element { View view = (View)mActivity.findViewById(mId); if(view != null) { if (!view.performClick()) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_WARN, + FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN, "Robocop called click on an element with no listener"); } } else { @@ -88,7 +88,7 @@ public class FennecNativeElement implements Element { try { syncQueue.take(); } catch (InterruptedException e) { - e.printStackTrace(); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e); } } @@ -129,7 +129,7 @@ public class FennecNativeElement implements Element { // Wait for the UiThread code to finish running syncQueue.take(); } catch (InterruptedException e) { - e.printStackTrace(); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e); } if (mText == null) { throw new RoboCopException("getText: Text is null for view "+mId); @@ -155,7 +155,7 @@ public class FennecNativeElement implements Element { try { syncQueue.take(); } catch (InterruptedException e) { - e.printStackTrace(); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e); } return mDisplayed; } diff --git a/build/mobile/robocop/FennecTalosAssert.java.in b/build/mobile/robocop/FennecTalosAssert.java.in index 6726b039627..54842cdaec9 100644 --- a/build/mobile/robocop/FennecTalosAssert.java.in +++ b/build/mobile/robocop/FennecTalosAssert.java.in @@ -46,12 +46,12 @@ public class FennecTalosAssert implements Assert { * Write information to a logfile and logcat */ public void dumpLog(String message) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message); } /** Write information to a logfile and logcat */ public void dumpLog(String message, Throwable t) { - FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message, t); } /** diff --git a/build/mobile/robocop/PaintedSurface.java.in b/build/mobile/robocop/PaintedSurface.java.in index 98bc0d58bef..1a505cf5613 100644 --- a/build/mobile/robocop/PaintedSurface.java.in +++ b/build/mobile/robocop/PaintedSurface.java.in @@ -29,9 +29,9 @@ public class PaintedSurface { FileInputStream pixelFile = new FileInputStream(filename); mPixelBuffer = pixelFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, pixelSize); } catch (java.io.FileNotFoundException e) { - e.printStackTrace(); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e); } catch (java.io.IOException e) { - e.printStackTrace(); + FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e); } } diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 46301f2ac59..3d360eda9a9 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -1048,13 +1048,14 @@ ScriptAnalysis::killVariable(JSContext *cx, LifetimeVariable &var, unsigned offs { if (!var.lifetime) { /* Make a point lifetime indicating the write. */ - if (!var.saved) - saved[savedCount++] = &var; - var.saved = cx->typeLifoAlloc().new_(offset, var.savedEnd, var.saved); - if (!var.saved) { + Lifetime *lifetime = cx->typeLifoAlloc().new_(offset, var.savedEnd, var.saved); + if (!lifetime) { setOOM(cx); return; } + if (!var.saved) + saved[savedCount++] = &var; + var.saved = lifetime; var.saved->write = true; var.savedEnd = 0; return; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 31922ff2325..028ec434a1f 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -2726,13 +2726,13 @@ TypeObject::getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force return; } - TypeSet *protoTypes = proto->type()->getProperty(cx, id, false); + TypeSet *protoTypes = proto->getType(cx)->getProperty(cx, id, false); if (!protoTypes) return; protoTypes->addSubset(cx, types); - proto->type()->getFromPrototypes(cx, id, protoTypes); + proto->getType(cx)->getFromPrototypes(cx, id, protoTypes); } static inline void @@ -5310,8 +5310,10 @@ JSScript::makeTypes(JSContext *cx) if (!cx->typeInferenceEnabled()) { types = (TypeScript *) cx->calloc_(sizeof(TypeScript)); - if (!types) + if (!types) { + js_ReportOutOfMemory(cx); return false; + } new(types) TypeScript(); return true; } @@ -5520,16 +5522,24 @@ JSObject::splicePrototype(JSContext *cx, JSObject *proto) void JSObject::makeLazyType(JSContext *cx) { - JS_ASSERT(cx->typeInferenceEnabled() && hasLazyType()); - AutoEnterTypeInference enter(cx); + JS_ASSERT(hasLazyType()); TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, JSProto_Object, getProto()); if (!type) { - cx->compartment->types.setPendingNukeTypes(cx); + if (cx->typeInferenceEnabled()) + cx->compartment->types.setPendingNukeTypes(cx); return; } + if (!cx->typeInferenceEnabled()) { + /* This can only happen if types were previously nuked. */ + type_ = type; + return; + } + + AutoEnterTypeInference enter(cx); + /* Fill in the type according to the state of this object. */ type->singleton = this; diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 29f4874c240..c3a994e096b 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -329,7 +329,7 @@ MarkIteratorUnknown(JSContext *cx) * Monitor a javascript call, either on entry to the interpreter or made * from within the interpreter. */ -inline void +inline bool TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) { extern void TypeMonitorCallSlow(JSContext *cx, JSObject *callee, @@ -341,11 +341,13 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) if (fun->isInterpreted()) { JSScript *script = fun->script(); if (!script->ensureRanAnalysis(cx, fun->environment())) - return; + return false; if (cx->typeInferenceEnabled()) TypeMonitorCallSlow(cx, callee, args, constructing); } } + + return true; } inline bool diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 258457dca79..2d5c2845f9e 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -515,7 +515,8 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct) if (fun->isNative()) return CallJSNative(cx, fun->native(), args); - TypeMonitorCall(cx, args, construct); + if (!TypeMonitorCall(cx, args, construct)) + return false; /* Get pointer to new frame/slots, prepare arguments. */ InvokeFrameGuard ifg; @@ -2693,7 +2694,8 @@ BEGIN_CASE(JSOP_FUNCALL) DO_NEXT_OP(len); } - TypeMonitorCall(cx, args, construct); + if (!TypeMonitorCall(cx, args, construct)) + goto error; InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE; diff --git a/js/src/methodjit/BaseCompiler.h b/js/src/methodjit/BaseCompiler.h index cf9efa9349c..24f65022da4 100644 --- a/js/src/methodjit/BaseCompiler.h +++ b/js/src/methodjit/BaseCompiler.h @@ -138,9 +138,7 @@ class LinkerHelper : public JSC::LinkBuffer } bool verifyRange(const JSC::JITCode &other) { -#ifdef DEBUG - verifiedRange = true; -#endif + markVerified(); #ifdef JS_CPU_X64 return VerifyRange(m_code, m_size, other.start(), other.size()); #else @@ -162,6 +160,7 @@ class LinkerHelper : public JSC::LinkBuffer JSC::ExecutablePool *pool; m_code = executableAllocAndCopy(masm, allocator, &pool); if (!m_code) { + markVerified(); js_ReportOutOfMemory(cx); return NULL; } @@ -186,6 +185,13 @@ class LinkerHelper : public JSC::LinkBuffer size_t size() const { return m_size; } + + protected: + void markVerified() { +#ifdef DEBUG + verifiedRange = true; +#endif + } }; class NativeStubLinker : public LinkerHelper diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp index e36d7add87b..c47cddc4a99 100644 --- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -298,7 +298,8 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial, bool newType = construct && cx->typeInferenceEnabled() && types::UseNewType(cx, f.script(), f.pc()); - types::TypeMonitorCall(cx, args, construct); + if (!types::TypeMonitorCall(cx, args, construct)) + return false; /* Try to compile if not already compiled. */ CompileStatus status = CanMethodJIT(cx, newscript, newscript->code, construct, CompileRequest_Interpreter); diff --git a/js/src/methodjit/MonoIC.cpp b/js/src/methodjit/MonoIC.cpp index 7ec129a7e56..e4f15148d0d 100644 --- a/js/src/methodjit/MonoIC.cpp +++ b/js/src/methodjit/MonoIC.cpp @@ -222,6 +222,7 @@ class EqualityICLinker : public LinkerHelper return false; JS_ASSERT(!f.regs.inlined()); if (!f.chunk()->execPools.append(pool)) { + markVerified(); pool->release(); js_ReportOutOfMemory(cx); return false; @@ -438,6 +439,7 @@ NativeStubLinker::init(JSContext *cx) stub.pool = pool; stub.jump = locationOf(done); if (!chunk->nativeCallStubs.append(stub)) { + markVerified(); pool->release(); return false; } diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index 1e183c2bd67..c4c674e8187 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -86,6 +86,7 @@ class PICLinker : public LinkerHelper if (!pool) return false; if (!ic.addPool(cx, pool)) { + markVerified(); pool->release(); js_ReportOutOfMemory(cx); return false; diff --git a/js/src/methodjit/Retcon.cpp b/js/src/methodjit/Retcon.cpp index 5be0836f274..0dd1a740bd1 100644 --- a/js/src/methodjit/Retcon.cpp +++ b/js/src/methodjit/Retcon.cpp @@ -362,6 +362,8 @@ ClearAllFrames(JSCompartment *compartment) ExpandInlineFrames(compartment); + compartment->types.recompilations++; + for (VMFrame *f = compartment->jaegerCompartment()->activeFrame(); f != NULL; f = f->previous) { diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 1c01ed09bad..f1716d797af 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -363,7 +363,7 @@ pref("places.frecency.unvisitedTypedBonus", 200); pref("gfx.color_management.mode", 0); #ifdef ANDROID // 0=fixed margin, 1=velocity bias, 2=dynamic resolution, 3=no margins -pref("gfx.displayport.strategy", 0); +pref("gfx.displayport.strategy", 1); #endif // don't allow JS to move and resize existing windows diff --git a/mobile/android/base/gfx/DisplayPortCalculator.java b/mobile/android/base/gfx/DisplayPortCalculator.java index fb281aa9e4d..f6b081db28c 100644 --- a/mobile/android/base/gfx/DisplayPortCalculator.java +++ b/mobile/android/base/gfx/DisplayPortCalculator.java @@ -15,7 +15,7 @@ final class DisplayPortCalculator { private static final String LOGTAG = "GeckoDisplayPortCalculator"; private static final PointF ZERO_VELOCITY = new PointF(0, 0); - private static DisplayPortStrategy sStrategy = new FixedMarginStrategy(); + private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy(); static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { return sStrategy.calculate(metrics, (velocity == null ? ZERO_VELOCITY : velocity)); @@ -216,14 +216,17 @@ final class DisplayPortCalculator { * they are affected by the panning velocity. Specifically, if we are panning on one axis, * we remove the margins on the other axis because we are likely axis-locked. Also once * we are panning in one direction above a certain threshold velocity, we shift the buffer - * so that it is entirely in the direction of the pan. + * so that it is almost entirely in the direction of the pan, with a little bit in the + * reverse direction. */ private static class VelocityBiasStrategy implements DisplayPortStrategy { // The length of each axis of the display port will be the corresponding view length // multiplied by this factor. - private static final float SIZE_MULTIPLIER = 1.2f; + private static final float SIZE_MULTIPLIER = 1.5f; // The velocity above which we apply the velocity bias private static final float VELOCITY_THRESHOLD = GeckoAppShell.getDpi() / 32f; + // How much of the buffer to keep in the reverse direction of the velocity + private static final float REVERSE_BUFFER = 0.2f; public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; @@ -249,21 +252,23 @@ final class DisplayPortCalculator { // the display port. RectF margins = new RectF(); if (velocity.x > VELOCITY_THRESHOLD) { - margins.right = horizontalBuffer; + margins.left = horizontalBuffer * REVERSE_BUFFER; } else if (velocity.x < -VELOCITY_THRESHOLD) { - margins.left = horizontalBuffer; + margins.left = horizontalBuffer * (1.0f - REVERSE_BUFFER); } else { margins.left = horizontalBuffer / 2.0f; - margins.right = horizontalBuffer - margins.left; } + margins.right = horizontalBuffer - margins.left; + if (velocity.y > VELOCITY_THRESHOLD) { - margins.bottom = verticalBuffer; + margins.top = verticalBuffer * REVERSE_BUFFER; } else if (velocity.y < -VELOCITY_THRESHOLD) { - margins.top = verticalBuffer; + margins.top = verticalBuffer * (1.0f - REVERSE_BUFFER); } else { margins.top = verticalBuffer / 2.0f; - margins.bottom = verticalBuffer - margins.top; } + margins.bottom = verticalBuffer - margins.top; + // and finally shift the margins to account for page bounds margins = shiftMarginsForPageBounds(margins, metrics); diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py index e63fcf00c1d..b632f692580 100644 --- a/testing/marionette/client/marionette/marionette.py +++ b/testing/marionette/client/marionette/marionette.py @@ -70,7 +70,7 @@ class HTMLElement(object): return self.marionette.find_elements(method, target, self.id) def get_attribute(self, attribute): - return self.marionette._send_message('getElementAttribute', 'value', element=self.id, name=attribute) + return self.marionette._send_message('getAttributeValue', 'value', element=self.id, name=attribute) def click(self): return self.marionette._send_message('clickElement', 'ok', element=self.id) diff --git a/testing/marionette/client/marionette/tests/unit/test_click.py b/testing/marionette/client/marionette/tests/unit/test_click.py index 0f226086487..739ed7dc1d6 100644 --- a/testing/marionette/client/marionette/tests/unit/test_click.py +++ b/testing/marionette/client/marionette/tests/unit/test_click.py @@ -44,3 +44,29 @@ class TestClick(MarionetteTestCase): link.click() self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;")) +class TestClickChrome(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) + + def test_click(self): + wins = self.marionette.get_windows() + wins.remove(self.win) + newWin = wins.pop() + self.marionette.switch_to_window(newWin) + box = self.marionette.find_element("id", "testBox") + self.assertFalse(self.marionette.execute_script("return arguments[0].checked;", [box])) + box.click() + self.assertTrue(self.marionette.execute_script("return arguments[0].checked;", [box])) diff --git a/testing/marionette/client/marionette/tests/unit/test_elementState.py b/testing/marionette/client/marionette/tests/unit/test_elementState.py new file mode 100644 index 00000000000..6a0d3423fe5 --- /dev/null +++ b/testing/marionette/client/marionette/tests/unit/test_elementState.py @@ -0,0 +1,86 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (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.mozilla.org/MPL/ # +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Marionette Client. +# +# The Initial Developer of the Original Code is +# Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +import os +from marionette_test import MarionetteTestCase + +class TestState(MarionetteTestCase): + def test_isEnabled(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("name", "myCheckBox") + self.assertTrue(l.enabled()) + self.marionette.execute_script("arguments[0].disabled = true;", [l]) + self.assertFalse(l.enabled()) + + def test_isDisplayed(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("name", "myCheckBox") + self.assertTrue(l.displayed()) + self.marionette.execute_script("arguments[0].hidden = true;", [l]) + self.assertFalse(l.displayed()) + +class TestStateChrome(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) + + def test_isEnabled(self): + l = self.marionette.find_element("id", "textInput") + self.assertTrue(l.enabled()) + self.marionette.execute_script("arguments[0].disabled = true;", [l]) + self.assertFalse(l.enabled()) + self.marionette.execute_script("arguments[0].disabled = false;", [l]) + + def test_isDisplayed(self): + l = self.marionette.find_element("id", "textInput") + self.assertTrue(l.displayed()) + self.marionette.execute_script("arguments[0].hidden = true;", [l]) + self.assertFalse(l.displayed()) + self.marionette.execute_script("arguments[0].hidden = false;", [l]) + diff --git a/testing/marionette/client/marionette/tests/unit/test_findelement.py b/testing/marionette/client/marionette/tests/unit/test_findelement.py index bdb9c92fa44..43638030be3 100644 --- a/testing/marionette/client/marionette/tests/unit/test_findelement.py +++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py @@ -45,7 +45,24 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementById('mozLink');") found_el = self.marionette.find_element("id", "mozLink") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) + + def test_child_element(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + el = self.marionette.find_element("id", "divLink") + div = self.marionette.find_element("id", "testDiv") + found_el = div.find_element("tag name", "a") + self.assertEqual(HTMLElement, type(found_el)) + self.assertEqual(el.id, found_el.id) + + def test_child_elements(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + el = self.marionette.find_element("id", "divLink2") + div = self.marionette.find_element("id", "testDiv") + found_els = div.find_elements("tag name", "a") + self.assertTrue(el.id in [found_el.id for found_el in found_els]) def test_tag_name(self): test_html = self.marionette.absolute_url("test.html") @@ -53,7 +70,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementsByTagName('body')[0];") found_el = self.marionette.find_element("tag name", "body") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_class_name(self): test_html = self.marionette.absolute_url("test.html") @@ -61,7 +78,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementsByClassName('linkClass')[0];") found_el = self.marionette.find_element("class name", "linkClass") self.assertEqual(HTMLElement, type(found_el)); - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_name(self): test_html = self.marionette.absolute_url("test.html") @@ -69,7 +86,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementsByName('myInput')[0];") found_el = self.marionette.find_element("name", "myInput") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_selector(self): test_html = self.marionette.absolute_url("test.html") @@ -77,7 +94,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementById('testh1');") found_el = self.marionette.find_element("css selector", "h1") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_link_text(self): test_html = self.marionette.absolute_url("test.html") @@ -85,7 +102,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementById('mozLink');") found_el = self.marionette.find_element("link text", "Click me!") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_partial_link_text(self): test_html = self.marionette.absolute_url("test.html") @@ -93,7 +110,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementById('mozLink');") found_el = self.marionette.find_element("partial link text", "Click m") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_xpath(self): test_html = self.marionette.absolute_url("test.html") @@ -101,7 +118,7 @@ class TestElements(MarionetteTestCase): el = self.marionette.execute_script("return window.document.getElementById('mozLink');") found_el = self.marionette.find_element("xpath", "id('mozLink')") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_not_found(self): test_html = self.marionette.absolute_url("test.html") @@ -120,30 +137,55 @@ class TestElementsChrome(MarionetteTestCase): def setUp(self): MarionetteTestCase.setUp(self) self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) def test_id(self): - el = self.marionette.execute_script("return window.document.getElementById('main-window');") - found_el = self.marionette.find_element("id", "main-window") + el = self.marionette.execute_script("return window.document.getElementById('textInput');") + found_el = self.marionette.find_element("id", "textInput") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) + + def test_child_element(self): + el = self.marionette.find_element("id", "textInput") + parent = self.marionette.find_element("id", "things") + found_el = parent.find_element("tag name", "textbox") + self.assertEqual(HTMLElement, type(found_el)) + self.assertEqual(el.id, found_el.id) + + def test_child_elements(self): + el = self.marionette.find_element("id", "textInput3") + parent = self.marionette.find_element("id", "things") + found_els = parent.find_elements("tag name", "textbox") + self.assertTrue(el.id in [found_el.id for found_el in found_els]) def test_tag_name(self): - el = self.marionette.execute_script("return window.document.getElementsByTagName('window')[0];") - found_el = self.marionette.find_element("tag name", "window") + el = self.marionette.execute_script("return window.document.getElementsByTagName('vbox')[0];") + found_el = self.marionette.find_element("tag name", "vbox") self.assertEqual(HTMLElement, type(found_el)) - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_class_name(self): - el = self.marionette.execute_script("return window.document.getElementsByClassName('editBookmarkPanelHeaderButton')[0];") - found_el = self.marionette.find_element("class name", "editBookmarkPanelHeaderButton") + el = self.marionette.execute_script("return window.document.getElementsByClassName('asdf')[0];") + found_el = self.marionette.find_element("class name", "asdf") self.assertEqual(HTMLElement, type(found_el)); - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_xpath(self): - el = self.marionette.execute_script("return window.document.getElementById('main-window');") - found_el = self.marionette.find_element("xpath", "id('main-window')") + el = self.marionette.execute_script("return window.document.getElementById('testBox');") + found_el = self.marionette.find_element("xpath", "id('testBox')") self.assertEqual(HTMLElement, type(found_el)); - self.assertTrue(el.id, found_el.id) + self.assertEqual(el.id, found_el.id) def test_not_found(self): self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page") @@ -152,6 +194,6 @@ class TestElementsChrome(MarionetteTestCase): def test_timeout(self): self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "myid") self.assertTrue(True, self.marionette.set_search_timeout(4000)) - self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('main-window').appendChild(b);}, 1000)") + self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('things').appendChild(b);}, 1000)") self.assertEqual(HTMLElement, type(self.marionette.find_element("id", "myid"))) - self.marionette.execute_script("window.document.getElementById('main-window').removeChild(window.document.getElementById('myid'));") + self.marionette.execute_script("window.document.getElementById('things').removeChild(window.document.getElementById('myid'));") diff --git a/testing/marionette/client/marionette/tests/unit/test_getattr.py b/testing/marionette/client/marionette/tests/unit/test_getattr.py new file mode 100644 index 00000000000..023d7e9f1d6 --- /dev/null +++ b/testing/marionette/client/marionette/tests/unit/test_getattr.py @@ -0,0 +1,67 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (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.mozilla.org/MPL/ # +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Marionette Client. +# +# The Initial Developer of the Original Code is +# Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +import os +from marionette_test import MarionetteTestCase + +class TestGetAttribute(MarionetteTestCase): + def test_getAttribute(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("id", "mozLink") + self.assertEqual("mozLink", l.get_attribute("id")) + +class TestGetAttributeChrome(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) + + def test_getAttribute(self): + el = self.marionette.execute_script("return window.document.getElementById('textInput');") + found_el = self.marionette.find_element("id", "textInput") + self.assertEqual(el.get_attribute("id"), "textInput") + diff --git a/testing/marionette/client/marionette/tests/unit/test_selected.py b/testing/marionette/client/marionette/tests/unit/test_selected.py new file mode 100644 index 00000000000..10a09f5e9aa --- /dev/null +++ b/testing/marionette/client/marionette/tests/unit/test_selected.py @@ -0,0 +1,73 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (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.mozilla.org/MPL/ # +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Marionette Client. +# +# The Initial Developer of the Original Code is +# Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +import os +from marionette_test import MarionetteTestCase + +class TestSelected(MarionetteTestCase): + def test_selected(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + box = self.marionette.find_element("name", "myCheckBox") + self.assertFalse(box.selected()) + box.click() + self.assertTrue(box.selected()) + +class TestSelectedChrome(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) + + def test_selected(self): + wins = self.marionette.get_windows() + wins.remove(self.win) + newWin = wins.pop() + self.marionette.switch_to_window(newWin) + box = self.marionette.find_element("id", "testBox") + self.assertFalse(box.selected()) + self.assertFalse(self.marionette.execute_script("arguments[0].checked = true;", [box])) + self.assertTrue(box.selected()) diff --git a/testing/marionette/client/marionette/tests/unit/test_text.py b/testing/marionette/client/marionette/tests/unit/test_text.py new file mode 100644 index 00000000000..24e62c590a6 --- /dev/null +++ b/testing/marionette/client/marionette/tests/unit/test_text.py @@ -0,0 +1,105 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (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.mozilla.org/MPL/ # +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is Marionette Client. +# +# The Initial Developer of the Original Code is +# Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +import os +from marionette_test import MarionetteTestCase + +class TestText(MarionetteTestCase): + def test_getText(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("id", "mozLink") + self.assertEqual("Click me!", l.text()) + + def test_clearText(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("name", "myInput") + self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l])) + l.clear() + self.assertEqual("", self.marionette.execute_script("return arguments[0].value;", [l])) + + def test_sendKeys(self): + test_html = self.marionette.absolute_url("test.html") + self.marionette.navigate(test_html) + l = self.marionette.find_element("name", "myInput") + self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l])) + l.send_keys("o") + self.assertEqual("asdfo", self.marionette.execute_script("return arguments[0].value;", [l])) + +class TestTextChrome(MarionetteTestCase): + def setUp(self): + MarionetteTestCase.setUp(self) + self.marionette.set_context("chrome") + self.win = self.marionette.get_window() + #need to get the file:// path for xul + unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir)) + tests = os.path.abspath(os.path.join(unit, os.path.pardir)) + mpath = os.path.abspath(os.path.join(tests, os.path.pardir)) + xul = "file://" + os.path.join(mpath, "www", "test.xul") + self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');") + + def tearDown(self): + self.marionette.execute_script("window.close();") + self.marionette.switch_to_window(self.win) + MarionetteTestCase.tearDown(self) + + def test_getText(self): + wins = self.marionette.get_windows() + wins.remove(self.win) + newWin = wins.pop() + self.marionette.switch_to_window(newWin) + box = self.marionette.find_element("id", "textInput") + self.assertEqual("test", box.text()) + + def test_clearText(self): + wins = self.marionette.get_windows() + wins.remove(self.win) + newWin = wins.pop() + self.marionette.switch_to_window(newWin) + box = self.marionette.find_element("id", "textInput") + self.assertEqual("test", box.text()) + box.clear() + self.assertEqual("", box.text()) + + def test_sendKeys(self): + wins = self.marionette.get_windows() + wins.remove(self.win) + newWin = wins.pop() + self.marionette.switch_to_window(newWin) + box = self.marionette.find_element("id", "textInput") + self.assertEqual("test", box.text()) + box.send_keys("at") + self.assertEqual("attest", box.text()) diff --git a/testing/marionette/client/marionette/tests/unit/unit-tests.ini b/testing/marionette/client/marionette/tests/unit/unit-tests.ini index 809879b3465..5f7b11b873d 100644 --- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini +++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini @@ -1,5 +1,13 @@ [test_click.py] b2g = false +[test_selected.py] +b2g = false +[test_getattr.py] +b2g = false +[test_elementState.py] +b2g = false +[test_text.py] +b2g = false [test_log.py] [test_execute_async_script.py] diff --git a/testing/marionette/client/marionette/www/test.html b/testing/marionette/client/marionette/www/test.html index b5a7bcc0177..db91d64da4d 100644 --- a/testing/marionette/client/marionette/www/test.html +++ b/testing/marionette/client/marionette/www/test.html @@ -21,7 +21,11 @@ } Click me! - Click me! - + + + diff --git a/testing/marionette/client/marionette/www/test.xul b/testing/marionette/client/marionette/www/test.xul new file mode 100644 index 00000000000..5b8aef24382 --- /dev/null +++ b/testing/marionette/client/marionette/www/test.xul @@ -0,0 +1,15 @@ + + + + + + + + + + + + +