diff --git a/core/actionProxy/actionproxy.py b/core/actionProxy/actionproxy.py
index 4266f5c777a782eff236823606326ba4a08f0bf7..3c3c84005ff679fe206c9bfd81bcfcb6d03ec400 100644
--- a/core/actionProxy/actionproxy.py
+++ b/core/actionProxy/actionproxy.py
@@ -91,13 +91,14 @@ class ActionRunner:
         return (os.path.isfile(self.binary) and os.access(self.binary, os.X_OK))
 
     # constructs an environment for the action to run in
-    # @param message is a JSON object received from invoker (should contain 'value' and 'authKey')
+    # @param message is a JSON object received from invoker (should contain 'value' and 'api_key' and other metadata)
     # @return an environment dictionary for the action process
     def env(self, message):
         # make sure to include all the env vars passed in by the invoker
         env = os.environ
-        if 'authKey' in message:
-            env['AUTH_KEY'] = message['authKey']
+        for p in [ 'api_key', 'namespace', 'action_name', 'activation_id', 'deadline' ]:
+             if p in message:
+                env['__OW_%s' % p.upper()] = message[p]
         return env
 
     # runs the action, called iff self.verify() is True.
diff --git a/core/nodejsAction/Dockerfile b/core/nodejsAction/Dockerfile
index 6af9760be46dbc7e84950f50abf240ed1ef5c0d1..1abd89e974eb4db4858bc578779f220b4ae4956b 100644
--- a/core/nodejsAction/Dockerfile
+++ b/core/nodejsAction/Dockerfile
@@ -34,6 +34,7 @@ mustache@2.1.3 \
 nano@5.10.0 \
 node-uuid@1.4.2 \
 oauth2-server@2.4.0 \
+openwhisk@2.6.0 \
 process@0.11.0 \
 request@2.79.0 \
 rimraf@2.5.1 \
diff --git a/tests/src/actionContainers/ActionProxyContainerTests.scala b/tests/src/actionContainers/ActionProxyContainerTests.scala
index 110b77b3fad097d1463bcd72358cb4faaecafcd5..8584b85ea3d3de2ef72bb002f1dd6f450b9ba85a 100644
--- a/tests/src/actionContainers/ActionProxyContainerTests.scala
+++ b/tests/src/actionContainers/ActionProxyContainerTests.scala
@@ -26,12 +26,8 @@ import org.scalatest.junit.JUnitRunner
 import ActionContainer.withContainer
 import common.TestUtils
 import common.WskActorSystem
-import spray.json.JsArray
-import spray.json.JsNull
-import spray.json.JsNumber
-import spray.json.JsObject
-import spray.json.JsString
-import spray.json.JsBoolean
+import spray.json.DefaultJsonProtocol._
+import spray.json._
 
 @RunWith(classOf[JUnitRunner])
 class ActionProxyContainerTests extends BasicActionRunnerTests with WskActorSystem {
@@ -81,20 +77,31 @@ class ActionProxyContainerTests extends BasicActionRunnerTests with WskActorSyst
     val stdEnvSamples = {
         val bash = """
                 |#!/bin/bash
-                |echo "{ \"auth\": \"$AUTH_KEY\", \"edge\": \"$EDGE_HOST\" }"
+                |echo "{ \
+                |\"api_host\": \"$__OW_API_HOST\", \"api_key\": \"$__OW_API_KEY\", \
+                |\"namespace\": \"$__OW_NAMESPACE\", \"action_name\": \"$__OW_ACTION_NAME\", \
+                |\"activation_id\": \"$__OW_ACTIVATION_ID\", \"deadline\": \"$__OW_DEADLINE\" }"
             """.stripMargin.trim
 
         val python = """
                 |#!/usr/bin/env python
                 |import os
-                |print '{ "auth": "%s", "edge": "%s" }' % (os.environ['AUTH_KEY'], os.environ['EDGE_HOST'])
+                |
+                |print '{ "api_host": "%s", "api_key": "%s", "namespace": "%s", "action_name" : "%s", "activation_id": "%s", "deadline": "%s" }' % (
+                |  os.environ['__OW_API_HOST'], os.environ['__OW_API_KEY'],
+                |  os.environ['__OW_NAMESPACE'], os.environ['__OW_ACTION_NAME'],
+                |  os.environ['__OW_ACTIVATION_ID'], os.environ['__OW_DEADLINE'])
             """.stripMargin.trim
 
         val perl = """
                 |#!/usr/bin/env perl
-                |$a = $ENV{'AUTH_KEY'};
-                |$e = $ENV{'EDGE_HOST'};
-                |print "{ \"auth\": \"$a\", \"edge\": \"$e\" }";
+                |$a = $ENV{'__OW_API_HOST'};
+                |$b = $ENV{'__OW_API_KEY'};
+                |$c = $ENV{'__OW_NAMESPACE'};
+                |$d = $ENV{'__OW_ACTION_NAME'};
+                |$e = $ENV{'__OW_ACTIVATION_ID'};
+                |$f = $ENV{'__OW_DEADLINE'};
+                |print "{ \"api_host\": \"$a\", \"api_key\": \"$b\", \"namespace\": \"$c\", \"action_name\": \"$d\", \"activation_id\": \"$e\", \"deadline\": \"$f\" }";
             """.stripMargin.trim
 
         // excluding perl as it not installed in alpine based image
@@ -244,28 +251,37 @@ trait BasicActionRunnerTests extends ActionProxyContainerTestUtils {
     }
 
     /** Runs tests for code samples which are expected to return the expected standard environment {auth, edge}. */
-    def testEnv(stdEnvSamples: Seq[(String, String)], enforceEmptyOutputStream: Boolean = true) = {
+    def testEnv(stdEnvSamples: Seq[(String, String)], enforceEmptyOutputStream: Boolean = true, enforceEmptyErrorStream: Boolean = true) = {
         for (s <- stdEnvSamples) {
             it should s"run a ${s._1} script and confirm expected environment variables" in {
-                val auth = JsString("abc")
-                val edge = "xyz"
-                val env = Map("EDGE_HOST" -> edge)
-
-                val (out, err) = withActionContainer(env) { c =>
+                val props = Seq(
+                    "api_host" -> "xyz",
+                    "api_key" -> "abc",
+                    "namespace" -> "zzz",
+                    "action_name" -> "xxx",
+                    "activation_id" -> "iii",
+                    "deadline" -> "123")
+                val env = props.map { case (k, v) => s"__OW_${k.toUpperCase()}" -> v }
+
+                val (out, err) = withActionContainer(env.take(1).toMap) { c =>
                     val (initCode, _) = c.init(initPayload(s._2))
                     initCode should be(200)
 
-                    val (runCode, out) = c.run(runPayload(JsObject(), Some(JsObject("authKey" -> auth))))
+                    val (runCode, out) = c.run(runPayload(JsObject(), Some(props.toMap.toJson.asJsObject)))
                     runCode should be(200)
                     out shouldBe defined
-                    out.get.fields("auth") shouldBe auth
-                    out.get.fields("edge") shouldBe JsString(edge)
+                    props.map {
+                        case (k, v) => withClue(k) {
+                            out.get.fields(k) shouldBe JsString(v)
+                        }
+
+                    }
                 }
 
                 checkStreams(out, err, {
                     case (o, e) =>
                         if (enforceEmptyOutputStream) o shouldBe empty
-                        e shouldBe empty
+                        if (enforceEmptyErrorStream) e shouldBe empty
                 })
             }
         }
diff --git a/tests/src/actionContainers/JavaActionContainerTests.scala b/tests/src/actionContainers/JavaActionContainerTests.scala
index 77bfff7a1efe2f40eca1713195502e026c9c7287..876f0b4ba28b163b5e755bcd47f8452382a7cb21 100644
--- a/tests/src/actionContainers/JavaActionContainerTests.scala
+++ b/tests/src/actionContainers/JavaActionContainerTests.scala
@@ -20,6 +20,7 @@ import org.junit.runner.RunWith
 import org.scalatest.FlatSpec
 import org.scalatest.Matchers
 import org.scalatest.junit.JUnitRunner
+import spray.json.DefaultJsonProtocol._
 import spray.json._
 
 import ActionContainer.withContainer
@@ -28,19 +29,62 @@ import ResourceHelpers.JarBuilder
 import common.WskActorSystem
 
 @RunWith(classOf[JUnitRunner])
-class JavaActionContainerTests extends FlatSpec with Matchers with WskActorSystem {
+class JavaActionContainerTests extends FlatSpec with Matchers with WskActorSystem with ActionProxyContainerTestUtils {
 
     // Helpers specific to javaaction
-    def withJavaContainer(code: ActionContainer => Unit) = withContainer("javaaction")(code)
+    def withJavaContainer(code: ActionContainer => Unit, env: Map[String, String] = Map.empty) = withContainer("javaaction", env)(code)
     def initPayload(mainClass: String, jar64: String) = JsObject(
         "value" -> JsObject(
             "name" -> JsString("dummyAction"),
             "main" -> JsString(mainClass),
             "jar" -> JsString(jar64)))
-    def runPayload(args: JsValue) = JsObject("value" -> args)
 
     behavior of "Java action"
 
+    it should s"run a java snippet and confirm expected environment variables" in {
+        val props = Seq("api_host" -> "xyz",
+            "api_key" -> "abc",
+            "namespace" -> "zzz",
+            "action_name" -> "xxx",
+            "activation_id" -> "iii",
+            "deadline" -> "123")
+        val env = props.map { case (k, v) => s"__OW_${k.toUpperCase}" -> v }
+        val (out, err) = withJavaContainer({ c =>
+            val jar = JarBuilder.mkBase64Jar(
+                Seq("example", "HelloWhisk.java") -> """
+                    | package example;
+                    |
+                    | import com.google.gson.JsonObject;
+                    |
+                    | public class HelloWhisk {
+                    |     public static JsonObject main(JsonObject args) {
+                    |         JsonObject response = new JsonObject();
+                    |         response.addProperty("api_host", System.getenv("__OW_API_HOST"));
+                    |         response.addProperty("api_key", System.getenv("__OW_API_KEY"));
+                    |         response.addProperty("namespace", System.getenv("__OW_NAMESPACE"));
+                    |         response.addProperty("action_name", System.getenv("__OW_ACTION_NAME"));
+                    |         response.addProperty("activation_id", System.getenv("__OW_ACTIVATION_ID"));
+                    |         response.addProperty("deadline", System.getenv("__OW_DEADLINE"));
+                    |         return response;
+                    |     }
+                    | }
+                """.stripMargin.trim)
+
+            val (initCode, _) = c.init(initPayload("example.HelloWhisk", jar))
+            initCode should be(200)
+
+            val (runCode, out) = c.run(runPayload(JsObject(), Some(props.toMap.toJson.asJsObject)))
+            runCode should be(200)
+            props.map {
+                case (k, v) => out.get.fields(k) shouldBe JsString(v)
+
+            }
+        }, env.take(1).toMap)
+
+        out.trim shouldBe empty
+        err.trim shouldBe empty
+    }
+
     it should "support valid flows" in {
         val (out, err) = withJavaContainer { c =>
             val jar = JarBuilder.mkBase64Jar(
diff --git a/tests/src/actionContainers/NodeJsActionContainerTests.scala b/tests/src/actionContainers/NodeJsActionContainerTests.scala
index 395449dabd802f395e2920357e820fe8c4c5d7d9..f33e3e26c21103407b22e78cc7b2b96dd079574d 100644
--- a/tests/src/actionContainers/NodeJsActionContainerTests.scala
+++ b/tests/src/actionContainers/NodeJsActionContainerTests.scala
@@ -31,6 +31,8 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
 
     lazy val nodejsContainerImageName = "nodejsaction"
 
+    val hasDeprecationWarnings = true
+
     override def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit) = {
         withContainer(nodejsContainerImageName, env)(code)
     }
@@ -68,6 +70,21 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
           """.stripMargin)
     })
 
+    testEnv(Seq {
+        ("node", """
+         |function main(args) {
+         |    return {
+         |       "api_host": process.env['__OW_API_HOST'],
+         |       "api_key": process.env['__OW_API_KEY'],
+         |       "namespace": process.env['__OW_NAMESPACE'],
+         |       "action_name": process.env['__OW_ACTION_NAME'],
+         |       "activation_id": process.env['__OW_ACTIVATION_ID'],
+         |       "deadline": process.env['__OW_DEADLINE']
+         |    }
+         |}
+         """.stripMargin.trim)
+    })
+
     it should "fail to initialize with bad code" in {
         val (out, err) = withNodeJsContainer { c =>
             val code = """
@@ -158,7 +175,7 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o shouldBe empty
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
         })
     }
 
@@ -180,7 +197,58 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o shouldBe empty
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
+        })
+    }
+
+    it should "warn when using deprecated whisk object methods" in {
+        val (out, err) = withNodeJsContainer { c =>
+            val code = """
+                | function main(args) {
+                |     whisk.getAuthKey(whisk.setAuthKey('xxx'));
+                |     try { whisk.invoke(); } catch (e) {}
+                |     try { whisk.trigger();  } catch (e) {}
+                |     setTimeout(function () { whisk.done(); }, 1000);
+                |     return whisk.async();
+                | }
+            """.stripMargin
+
+            c.init(initPayload(code))._1 should be(200)
+
+            val (runCode, runRes) = c.run(runPayload(JsObject()))
+            runCode should be(200)
+        }
+
+        checkStreams(out, err, {
+            case (o, e) =>
+                o shouldBe empty
+                e should not be empty
+                val lines = e.split("\n")
+                lines.filter { l => l.startsWith("[WARN] \"whisk.") && l.contains("deprecated") }.length shouldBe 8
+        })
+    }
+
+    it should "warn when using deprecated whisk.error" in {
+        val (out, err) = withNodeJsContainer { c =>
+            val code = """
+                | function main(args) {
+                |     whisk.error("{warnme: true}");
+                | }
+            """.stripMargin
+
+            c.init(initPayload(code))._1 should be(200)
+
+            val (runCode, runRes) = c.run(runPayload(JsObject()))
+            runCode should be(200)
+        }
+
+        checkStreams(out, err, {
+            case (o, e) =>
+                o shouldBe empty
+                e should not be empty
+                val lines = e.split("\n")
+                lines.length shouldBe 1
+                lines.forall { l => l.startsWith("[WARN] \"whisk.") && l.contains("deprecated") }
         })
     }
 
@@ -205,7 +273,7 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o should include("more than once")
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
         })
     }
 
@@ -243,7 +311,7 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o shouldBe empty
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
         }, 3)
     }
 
@@ -268,7 +336,7 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o shouldBe empty
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
         })
     }
 
@@ -302,7 +370,7 @@ class NodeJsActionContainerTests extends BasicActionRunnerTests with WskActorSys
         checkStreams(out, err, {
             case (o, e) =>
                 o shouldBe empty
-                e shouldBe empty
+                if (!hasDeprecationWarnings) e shouldBe empty
         }, 2)
     }
 
diff --git a/tests/src/actionContainers/PythonActionContainerTests.scala b/tests/src/actionContainers/PythonActionContainerTests.scala
index fe17476c12a8f8b9db4600938035e90c4ce75c0d..41968bf26e7a2189b9785989ca3204b0b9a3ca51 100644
--- a/tests/src/actionContainers/PythonActionContainerTests.scala
+++ b/tests/src/actionContainers/PythonActionContainerTests.scala
@@ -53,7 +53,14 @@ class PythonActionContainerTests extends BasicActionRunnerTests with WskActorSys
         ("python", """
          |import os
          |def main(dict):
-         |    return { "auth": os.environ['AUTH_KEY'], "edge": os.environ['EDGE_HOST'] }
+         |    return {
+         |       "api_host": os.environ['__OW_API_HOST'],
+         |       "api_key": os.environ['__OW_API_KEY'],
+         |       "namespace": os.environ['__OW_NAMESPACE'],
+         |       "action_name": os.environ['__OW_ACTION_NAME'],
+         |       "activation_id": os.environ['__OW_ACTIVATION_ID'],
+         |       "deadline": os.environ['__OW_DEADLINE']
+         |    }
          """.stripMargin.trim)
     })
 
diff --git a/tests/src/actionContainers/Swift3ActionContainerTests.scala b/tests/src/actionContainers/Swift3ActionContainerTests.scala
index f1f5bbde75d08fdbea22ca4aa008ed59754a050d..a294bea65b344d39eb9f859264d1adb2d9d65a83 100644
--- a/tests/src/actionContainers/Swift3ActionContainerTests.scala
+++ b/tests/src/actionContainers/Swift3ActionContainerTests.scala
@@ -27,20 +27,8 @@ class Swift3ActionContainerTests extends SwiftActionContainerTests {
 
     override val enforceEmptyOutputStream = false
     override lazy val swiftContainerImageName = "swift3action"
-    override lazy val envCode =  """
-         |func main(args: [String: Any]) -> [String: Any] {
-         |     let env = ProcessInfo.processInfo.environment
-         |     var auth = "???"
-         |     var edge = "???"
-         |     if let authKey : String = env["AUTH_KEY"] {
-         |         auth = "\(authKey)"
-         |     }
-         |     if let edgeHost : String = env["EDGE_HOST"] {
-         |         edge = "\(edgeHost)"
-         |     }
-         |     return ["auth": auth, "edge": edge]
-         |}
-         """.stripMargin
+    override lazy val envCode = makeEnvCode("ProcessInfo.processInfo")
+
     override lazy val errorCode = """
                 | // You need an indirection, or swiftc detects the div/0
                 | // at compile-time. Smart.
diff --git a/tests/src/actionContainers/SwiftActionContainerTests.scala b/tests/src/actionContainers/SwiftActionContainerTests.scala
index 44d965e26eb5d2b7841d9f5fbb0fe073c7dc2b51..cfe3ce2a81c96b92a82f5935f066cd564461a399 100644
--- a/tests/src/actionContainers/SwiftActionContainerTests.scala
+++ b/tests/src/actionContainers/SwiftActionContainerTests.scala
@@ -32,21 +32,38 @@ class SwiftActionContainerTests extends BasicActionRunnerTests with WskActorSyst
     // prints status messages and there doesn't seem to be a way to quiet them
     val enforceEmptyOutputStream = true
     lazy val swiftContainerImageName = "swiftaction"
+    lazy val envCode = makeEnvCode("NSProcessInfo.processInfo()")
 
-    lazy val envCode = """
+    def makeEnvCode(processInfo: String) = ("""
          |func main(args: [String: Any]) -> [String: Any] {
-         |     let env = NSProcessInfo.processInfo().environment
-         |     var auth = "???"
-         |     var edge = "???"
-         |     if let authKey : String = env["AUTH_KEY"] {
-         |         auth = "\(authKey)"
+         |     let env = """+processInfo+""".environment
+         |     var a = "???"
+         |     var b = "???"
+         |     var c = "???"
+         |     var d = "???"
+         |     var e = "???"
+         |     var f = "???"
+         |     if let v : String = env["__OW_API_HOST"] {
+         |         a = "\(v)"
          |     }
-         |     if let edgeHost : String = env["EDGE_HOST"] {
-         |         edge = "\(edgeHost)"
+         |     if let v : String = env["__OW_API_KEY"] {
+         |         b = "\(v)"
          |     }
-         |     return ["auth": auth, "edge": edge]
+         |     if let v : String = env["__OW_NAMESPACE"] {
+         |         c = "\(v)"
+         |     }
+         |     if let v : String = env["__OW_ACTION_NAME"] {
+         |         d = "\(v)"
+         |     }
+         |     if let v : String = env["__OW_ACTIVATION_ID"] {
+         |         e = "\(v)"
+         |     }
+         |     if let v : String = env["__OW_DEADLINE"] {
+         |         f = "\(v)"
+         |     }
+         |     return ["api_host": a, "api_key": b, "namespace": c, "action_name": d, "activation_id": e, "deadline": f]
          |}
-         """.stripMargin
+         """).stripMargin
 
     lazy val errorCode = """
                 | // You need an indirection, or swiftc detects the div/0
diff --git a/tests/src/system/basic/CLIPythonTests.scala b/tests/src/system/basic/CLIPythonTests.scala
index 2f00ca645254fdc5f307e5baf92b8dc96f5872eb..891745bc0e7b04db7f571101a60147c8854bb0d3 100644
--- a/tests/src/system/basic/CLIPythonTests.scala
+++ b/tests/src/system/basic/CLIPythonTests.scala
@@ -72,7 +72,7 @@ class CLIPythonTests
 
     it should "invoke an invalid action and get error back" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
-            val name = "basicInvoke"
+            val name = "bad code"
             assetHelper.withCleaner(wsk.action, name) {
                 (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("malformed.py")))
             }
diff --git a/tests/src/system/basic/WskActionTests.scala b/tests/src/system/basic/WskActionTests.scala
index 1cc8e8e0baca054d0eefac85f6d302cc8d274481..524eb20605db9331aaa78b0fa7c8d1f228cee55a 100644
--- a/tests/src/system/basic/WskActionTests.scala
+++ b/tests/src/system/basic/WskActionTests.scala
@@ -45,6 +45,22 @@ class WskActionTests
 
     behavior of "Whisk actions"
 
+    it should "invoke an action returning a promise" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val name = "hello promise"
+            assetHelper.withCleaner(wsk.action, name) {
+                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("helloPromise.js")))
+            }
+
+            val run = wsk.action.invoke(name)
+            withActivation(wsk.activation, run) {
+                activation =>
+                    activation.response.status shouldBe "success"
+                    activation.response.result shouldBe Some(JsObject("done" -> true.toJson))
+                    activation.logs.get.mkString(" ") shouldBe empty
+            }
+    }
+
     it should "invoke an action with a space in the name" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             val name = "hello Async"
@@ -169,7 +185,7 @@ class WskActionTests
             wsk.parseJsonString(rr.stdout).getFieldPath("exec", "code") shouldBe Some(JsString(""))
     }
 
-    it should "blocking invoke nested blocking actions" in withAssetCleaner(wskprops) {
+    it should "blocking invoke of nested blocking actions" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             val name = "nestedBlockingAction"
             val child = "wc"
diff --git a/tests/src/system/basic/WskBasicNodeTests.scala b/tests/src/system/basic/WskBasicNodeTests.scala
index 4e5fdca130bc5a53c43e0e58470d2de948757cfa..d78c7d620a99f8e993f138442b4c90db9f8ea090 100644
--- a/tests/src/system/basic/WskBasicNodeTests.scala
+++ b/tests/src/system/basic/WskBasicNodeTests.scala
@@ -113,6 +113,7 @@ class WskBasicNodeTests
             }
     }
 
+    // TODO: remove this tests and its assets when "whisk.js" is removed entirely as it is no longer necessary
     it should "Ensure that whisk.invoke() returns a promise" in withAssetCleaner(wskprops) {
         val expectedDuration = 3.seconds
 
@@ -165,6 +166,7 @@ class WskBasicNodeTests
             }
     }
 
+    // TODO: remove this tests and its assets when "whisk.js" is removed entirely as it is no longer necessary
     it should "Ensure that whisk.invoke() still uses a callback when provided one" in withAssetCleaner(wskprops) {
         val expectedDuration = 3.seconds
 
@@ -216,6 +218,7 @@ class WskBasicNodeTests
             }
     }
 
+    // TODO: remove this tests and its assets when "whisk.js" is removed entirely as it is no longer necessary
     it should "Ensure that whisk.trigger() still uses a callback when provided one" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             // this action supplies a 'next' callback to whisk.trigger()
@@ -251,6 +254,7 @@ class WskBasicNodeTests
             }
     }
 
+    // TODO: remove this tests and its assets when "whisk.js" is removed entirely as it is no longer necessary
     it should "Ensure that whisk.trigger() returns a promise" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             // this action supplies a 'next' callback to whisk.trigger()
diff --git a/tests/src/system/basic/WskBasicTests.scala b/tests/src/system/basic/WskBasicTests.scala
index 36c661dcb32bea4a4861d4cc699c3db3d30d8b50..1acfa4087fcaa55aa41e59580ab4434e13bd7a43 100644
--- a/tests/src/system/basic/WskBasicTests.scala
+++ b/tests/src/system/basic/WskBasicTests.scala
@@ -16,19 +16,15 @@
 
 package system.basic
 
-import java.time.Instant
 import java.io.File
+import java.time.Instant
 
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
 
 import common.TestHelpers
 import common.TestUtils
-import common.TestUtils.CONFLICT
-import common.TestUtils.SUCCESS_EXIT
-import common.TestUtils.UNAUTHORIZED
-import common.TestUtils.FORBIDDEN
-import common.TestUtils.ERROR_EXIT
+import common.TestUtils._
 import common.Wsk
 import common.WskProps
 import common.WskTestHelpers
@@ -361,15 +357,17 @@ class WskBasicTests
             }
     }
 
-    it should "create and invoke a blocking action resulting in an error response object" in withAssetCleaner(wskprops) {
+    it should "create and invoke a blocking action resulting in an failed promise" in withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             val name = "errorResponseObject"
             assetHelper.withCleaner(wsk.action, name) {
                 (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("asyncError.js")))
             }
 
-            wsk.action.invoke(name, blocking = true, expectedExitCode = 246)
-                .stderr should include regex (""""error": "name '!' contains illegal characters \(code \d+\)"""")
+            val stderr = wsk.action.invoke(name, blocking = true, expectedExitCode = 246).stderr
+            CliActivation.serdes.read(stderr.parseJson).response.result shouldBe Some {
+                JsObject("error" -> JsObject("msg" -> "failed activation on purpose".toJson))
+            }
     }
 
     it should "invoke a blocking action and get only the result" in withAssetCleaner(wskprops) {
diff --git a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
index e832c112c3212f721113c6db5f4e56a1a618adaf..0bf4198b744236be510f2a5074042d1e6887f2db 100644
--- a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -45,6 +45,8 @@ import whisk.core.entity.size.SizeInt
 import whisk.utils.retry
 import JsonArgsForTests._
 import whisk.http.Messages
+import common.WskAdmin
+import java.time.Clock
 
 /**
  * Tests for basic CLI usage. Some of these tests require a deployed backend.
@@ -452,6 +454,63 @@ class WskBasicUsageTests
             }
     }
 
+    it should "invoke an action using npm openwhisk" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val name = "hello npm openwhisk"
+            assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
+                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("helloOpenwhiskPackage.js")))
+            }
+
+            val run = wsk.action.invoke(name, Map("ignore_certs" -> true.toJson, "name" -> name.toJson))
+            withActivation(wsk.activation, run) {
+                activation =>
+                    activation.response.status shouldBe "success"
+                    activation.response.result shouldBe Some(JsObject("delete" -> true.toJson))
+                    activation.logs.get.mkString(" ") should include("action list has this many actions")
+            }
+
+            wsk.action.delete(name, expectedExitCode = TestUtils.NOT_FOUND)
+    }
+
+    it should "invoke an action receiving context properties" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val user = WskAdmin.getUser(wskprops.authKey)
+            val name = "context"
+            assetHelper.withCleaner(wsk.action, name) {
+                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("helloContext.js")))
+            }
+
+            val start = Instant.now(Clock.systemUTC()).toEpochMilli
+            val run = wsk.action.invoke(name)
+            withActivation(wsk.activation, run) {
+                activation =>
+                    activation.response.status shouldBe "success"
+                    val fields = activation.response.result.get.convertTo[Map[String, String]]
+                    fields("api_host") shouldBe WhiskProperties.getEdgeHost + ":" + WhiskProperties.getEdgeHostApiPort
+                    fields("api_key") shouldBe wskprops.authKey
+                    fields("namespace") shouldBe user
+                    fields("action_name") shouldBe s"/$user/$name"
+                    fields("activation_id") shouldBe activation.activationId
+                    fields("deadline").toLong should be >= start
+            }
+    }
+
+    it should s"invoke an action that returns a result by the deadline" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val name = "deadline"
+            assetHelper.withCleaner(wsk.action, name) {
+                (action, _) => action.create(name, Some(TestUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
+            }
+
+            val start = Instant.now(Clock.systemUTC()).toEpochMilli
+            val run = wsk.action.invoke(name)
+            withActivation(wsk.activation, run) {
+                activation =>
+                    activation.response.status shouldBe "success"
+                    activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
+            }
+    }
+
     behavior of "Wsk packages"
 
     it should "create, and get a package to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {